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

Frobenius Norm defined for vectors? #15533

Closed
TNonet opened this issue Feb 6, 2020 · 6 comments
Closed

Frobenius Norm defined for vectors? #15533

TNonet opened this issue Feb 6, 2020 · 6 comments

Comments

@TNonet
Copy link

TNonet commented Feb 6, 2020

This might be less of an implementation question, and more of a "philosophy" question, but shouldn't the Frobenius Norm work on Vectors? Source: Wolfram

Currently, the Frobenius Norm in numpy does not accept vectors:

import numpy as np
a = np.random.rand(10, 1)
b = np.squeeze(a)
print(np.linalg.norm(a, 'fro'))
print(np.linalg.norm(b, 'fro'))

Which results in:

1.7594677278427366
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
//anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py in norm(x, ord, axis, keepdims)
   2515             try:
-> 2516                 ord + 1
   2517             except TypeError:

TypeError: can only concatenate str (not "int") to str

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-18-2ace847024a5> in <module>
      3 b = np.squeeze(a)
      4 print(np.linalg.norm(a, 'fro'))
----> 5 print(np.linalg.norm(b, 'fro'))

<__array_function__ internals> in norm(*args, **kwargs)

//anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py in norm(x, ord, axis, keepdims)
   2516                 ord + 1
   2517             except TypeError:
-> 2518                 raise ValueError("Invalid norm order for vectors.")
   2519             absx = abs(x)
   2520             absx **= ord

ValueError: Invalid norm order for vectors.
@rossbar
Copy link
Contributor

rossbar commented Feb 6, 2020

This looks like a bug in the handling of the 'fro' kwarg:

>>> print(np.linalg.norm(b))
1.7547099704258247

Note that the Frobenius norm is the default when the ord kwarg is None.

@seberg
Copy link
Member

seberg commented Feb 6, 2020

xref gh-14719 and gh-14215: We thought about deprecating the general case, but then never went ahead because while there was not a huge resistance, there was some. And some other packages define it as that. So the issue is to decide where exactly to go here...

@seberg
Copy link
Member

seberg commented Feb 6, 2020

As Ross pointed out to me, the issue/PR I linked are only tangentially related and this is quite clearly a bug in the "fro" handling.

@rossbar
Copy link
Contributor

rossbar commented Feb 6, 2020

A PR to address the bug in the kwarg handling (and accompanying tests) is welcome! Nice catch @TNonet

@TNonet
Copy link
Author

TNonet commented Feb 7, 2020

Since this is my first issue, Are there any resources for making proper tests and a pull request?

(Also, if I was to clone the numpy repo and run setup.py, how would I make sure which numpy version I use when I import numpy?)

I would argue if ord is 'fro', then lines 2512-14 below.

numpy/numpy/linalg/linalg.py

Lines 2510 to 2524 in dae4f67

if axis is None:
ndim = x.ndim
if ((ord is None) or
(ord in ('f', 'fro') and ndim == 2) or
(ord == 2 and ndim == 1)):
x = x.ravel(order='K')
if isComplexType(x.dtype.type):
sqnorm = dot(x.real, x.real) + dot(x.imag, x.imag)
else:
sqnorm = dot(x, x)
ret = sqrt(sqnorm)
if keepdims:
ret = ret.reshape(ndim*[1])
return ret

Would need to be changed to:

if ((ord is None) or 
    (ord in ('f', 'fro')) or 
    (ord == 2 and ndim == 1)): 

Assuming everyone agrees that an nth order array has a Forbenious Norm that is naturally summing up squares of each element.

@rossbar
Copy link
Contributor

rossbar commented Feb 7, 2020

The problem is actually a bit further down in the code - if you follow the traceback from the error you received originally, you should be able to find the offending bit.

As mentioned in the discussions in #14719 and #14215, the behavior for >2 dimensions is a separate issue - it would be best if you could limit this PR to the bug in kwarg handling.

Re: resources for testing/contributing: take a look at NumPy's contribution guidelines. You can also take a look at linalg tests in numpy/linalg/tests/test_linalg.py to get an idea of how tests are formulated and where additional tests might be appropriate. Hope that helps!

TNonet added a commit to TNonet/numpy that referenced this issue Feb 7, 2020
Default parameters for norms implements the Frobenious Norm. See numpy#15533

When using ord='fro' should work for both vectors and arrays, as defined.
Jimver added a commit to Jimver/numpy that referenced this issue Mar 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants