JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.06k stars 5.43k forks source link

State of inner products in Base #25565

Closed juliohm closed 6 years ago

juliohm commented 6 years ago

If a user needs to define custom inner products for general Hilbert spaces, what is the current state in Base for this type of generalization? https://github.com/JuliaLang/julia/issues/16573 is a related, but less general issue. My concern is with new types that aren't arrays.

I'd like to propose renaming dot to inner, or perhaps directing users to define inner(x,y) as a general inner product between objects x and y, including the array case:

inner(x::AbstractVector, y::AbstractVector) = dot(x, y)

In case the change is reasonable, could it be part of Julia v1.0?

andreasnoack commented 6 years ago

Could you explain a little bit more about your use case and why having it in Base instead of just defining it in your package is beneficial? A concrete example would be best. Do you expect several inner definitions across packages loaded simultaneously?

juliohm commented 6 years ago

I think having a formal interface for these mathematical spaces will help users exploit the type system better. For example, I would expect clustering methods to work on any metric space. If I could define my type with an inner product, I would benefit from Clustering.jl out of the box (after the package is fixed accordingly). Many other distance-based or projection-based algorithms could also be generalized.

As a concrete example, I came across this limitation today trying to define a geometry for compositional data: https://github.com/juliohm/CoDa.jl I'd rather specialize on a well-known inner function defined in Base than define my own interface that no one else will be aware of.

andyferris commented 6 years ago

Why not extend dot for your Hilbert space types? I’m pretty sure it’s designed with being the generic inner product in mind.

juliohm commented 6 years ago

The concept of dot product is more strict than the concept of inner product. Whereas the latter is defined for general spaces, a dot product is only defined when there is the notion of a coordinate system defined by a finite basis. The semantics of dot(x,y) is x'*y where x and y represent coordinates of the objects in a Cartesian world. Mathematical textbooks will rarely mention the term dot product as the authors are usually interested treating the material in more general (not necessarily finite nor Euclidean) spaces.

To distinguish further, in a Hilbert space with inner product <x,y> (or inner(x,y)) objects can be infinite and the semantics x'*y doesn't apply. For example, in functional data analysis the objects are functions f and g and the inner product is usually obtained by numerical integration: inner(f,g) = quadrature(f*g). Calling this operation a dot product is misleading.

Another example as I pointed out in my CoDa.jl package is compositional data. Composition objects lie in a simplex world for which the operation x'*y doesn't make any sense. However, there exists a isometric transformation (the log-ratio transformation) that one can use to map compositions into another geometry where one can then apply the dot product with coordinates. Working with coordinates is not necessary, but it is common practice in this field. The result can be back transformed to the original space where the objects exist.

I don't see benefit in maintaining the term dot in the language, but if one asks for backward compatibility, the generalization inner(x::AbstractVector, y::AbstractVector) = dot(x,y) works perfectly.

Can you elaborate on the objections for this change?

StefanKarpinski commented 6 years ago

Can you elaborate on the objections for this change?

We generally require a fair amount of justification for adding new public functions to Base, that's the objection. This could be provided by an InnerProducts package. Why does it need to be built into the language itself? This was the first question that @andreasnoack asked above – it got a somewhat vague answer of "I think having a formal interface for these mathematical spaces will help users exploit the type system better". There's no reason that an interface defined in a package is any less formal than one in Base. What does having Base.inner offer that InnerProducts.inner doesn't? This is a genuine question that could have a convincing answer, but I don't know what that answer might be, which is why the question is being asked.

juliohm commented 6 years ago

I don't see a good argument to define a basic mathematical concept like inner products elsewhere that is not in Base. A language whose main audience is scientific computing folks would benefit from correct terminology. Why the concept of norm is defined in Base.LinAlg and inner, which is on the same cohort, should be defined in a package? Besides this inconsistency, the language already has dot, which makes me wonder why it should have something so specific rather than a more general concept?

StefanKarpinski commented 6 years ago

So you want all possible mathematical concepts in the base language? Not having something defined in Base doesn't force people to use the wrong terminology. The norm function is exported from LinAlg because it is defined and used in LinAlg. Similar for dot. Are you proposing that dot should be renamed to inner?

juliohm commented 6 years ago

So you want all possible mathematical concepts in the base language?

I never said that.

Not having something defined in Base doesn't force people to use the wrong terminology.

I am sure that it doesn't. Promoting the wrong terminology is the issue. People coming from a less mathematical background will adopt the usage of dot because they see it in Base. Usage of the term "dot" product to represent the concept of inner product is incorrect. It is also harmful to the mathematical community, which struggles every now and then to fix these scars that wrong terminology has left. Students from my generation are consistently having to refer to old books to get the terminology right, this shouldn't be the case.

Are you proposing that dot should be renamed to inner

That would already be a major improvement in my opinion. See all the examples I gave above on functional and compositional data. People in these communities would never use the term dot in their work. "dot" is more like a computer science term than anything else.

StefanKarpinski commented 6 years ago

Renaming dot to inner is quite a different proposal than adding inner to Base in addition to dot. That's more of a "correct terminology" question, which you and other linalg folks will have to hash out, although I seem to recall we bikeshedded this once and concluded that dot was the correct name for what this function implements.

andreasnoack commented 6 years ago

There was a little discussion of this in https://github.com/JuliaLang/julia/issues/22227 and https://github.com/JuliaLang/julia/pull/22220

juliohm commented 6 years ago

Renaming dot to inner is quite a different proposal than adding inner to Base in addition to dot.

This is what I proposed in my first message in this thread:

I'd like to propose renaming dot to inner, or perhaps directing users to define inner(x,y) as a general inner product between objects x and y

I repeat dot product is the incorrect term for the operation I am discussing here. Inner, outer, scalar product... these are mathematical objects. "dot product" is a computational object: it gets two sequences of numbers and performs x1*y1 + x2*y2 + ... xn*yn, a useless operation in other mathematical spaces.

StefanKarpinski commented 6 years ago

I had focused on the second option you proposed, which seems to have been adding Base.inner with a fallback to call Base.dot. Either option is possible, but both require some justification: to add a new operation, one needs a reason why it can't just be in a package (what the initial part of this discussion was about); to rename, it needs to be decided that dot is the wrong name and inner is the correct one (what the conversation seems to have turned to).

andyferris commented 6 years ago

@juliohm It's probably worth (re)stating that there is an active effort currently trying to shrink Base and encourage the use of packages. In this case dot seems to be correct for all the types participating in linear algebra provided in standard Julia (i.e. Number and Array - so yes, there is a definite, known, finite basis in all cases - thus I don't think we've made a mistake in terminology, though there may be better choices). I'm not against this proposal - but wanted to point this to clarify why you might be experiencing some "latent" resistance to change.

Also worth keeping in mind that a fair number of Julia newcomers may be familiar with a dot product but not an inner product (say, they did a bit of physics at university, but aren't math majors) so there are also some reasons to keep dot (not to mention that we have an infix operator that it corresponds with - we could just map it to inner I suppose but that's slightly less obvious). We also don't have an outer function, or a variety of other possible operations.

Thus, there is a burden to make a reasonable case for how putting this in Base (or LinAlg) is strictly better than putting this in a user package. The primary reason seems to be to provide an interface that can be shared and extended by others - is that a reasonable summary? The argument about letting generic code from Clustering.jl work with your inner product seems pretty compelling. Also, in the context that we seem to be splitting LinAlg into a stdlib package - I was thinking that if I were to author a package called LinearAlgebra I'd probably be happy to include an inner function for others to extend.

juliohm commented 6 years ago

Thank you @andyferris for sharing your thoughts. I see the resistance very clearly, which is something that I am not very excited about. Nevertheless, I am curious about how this specific proposal leads to code increase? To me, it seems like a trivial change in code with major improvement in abstraction. The example with Clustering.jl is just one of many, think of any kernel-based method that can be made to work with arbitrary Julia types for which the notion of inner product exists. MultivariateStats.jl has plenty of them.

juliohm commented 6 years ago

Regarding the comment about LinAlg split into a separate package, I agree that it seems like a good place to encapsulate mathematical products. I am assuming that this LinearAlgebra package of the future would be imported in a Julia session by default and so all users would have access to the concept of inner, outer, etc right away.

andyferris commented 6 years ago

Yes, the standard libraries are all built together with the Julia system image and available by default. At least for the v1.x series no-one will need to type using LinAlg (I don't think it will be renamed LinearAlgbebra, btw, I just made that up as a hypothetical competitor).

StefanKarpinski commented 6 years ago

To clarify, it would be loaded with standard Julia so you don't have to install anything, but you would still have to write using LinAlg to get the names it exports.

andyferris commented 6 years ago

This is where it gets odd, right, since we'll get the * methods and so-on without using LinAlg? (in other terms, LinAlg is a type pirate).

StefanKarpinski commented 6 years ago

Yes, that's basically where we'll have to draw the line: Base must define as much linear algebra functionality as needed to make LinAlg not a pirate, so matmul is defined in Base because Array and * both are. Funky matrix types and non-base operations live there though.

juliohm commented 6 years ago

Let me give you a concrete example and ask you how would you solve it with the current interface, maybe this can clarify things for me.

The goal is to perform factor analysis with compositional data. I have a type called a Composition and an inner product in the space of compositions. I collect many samples (e.g. rock samples) and put all of them into a big Vector{Composition} (e.g. composition = %water, %grain, %air). Now I want to call a factor analysis algorithm implemented in another package (e.g. MultivariateStats.jl) on this vector of data. How would you implement that generically without having an inner product imported by default?

What I understood from the last comments is that both MultivariateStats.jl and CoDa.jl would have to depend on LinAlg.jl. The dependency in MultivariateStats.jl is just to bring name inner into scope. The dependency in CoDa.jl is to define a method for inner that can be called by MultivariateStats.jl. Is that what you are suggesting?

andyferris commented 6 years ago

It seems Composition{D} is a D dimensional vector space under + and *.

I would be quite tempted to define the dual vector space.

So, you could define adjoint(::Composition) -> DualComposition and *(::DualComposition, ::Composition) -> scalar (currently inner). DualComposition wouldn't have to do much except hold a Composition inside.

andyferris commented 6 years ago

The first sentence in https://en.wikipedia.org/wiki/Dot_product does seem to suggest that dot could be an operation on any two iterables. We could make it recursive and define it for Number, and define inner as the abstract linear algebra function, which happens to overlap for Number and AbstractArray.

juliohm commented 6 years ago

Thank you @andyferris, I appreciate your thoughts on the dual space. I'd rather not rely on a new type for this task though. The final solution is unnecessarily complex.

What I am interested in understanding is why something like:

inner(x,y) = sum(x.*y)
norm(x) = sqrt(inner(x,x))

export inner, norm

not welcome in Base? I am assuming this is all that is required to define the function names generically for users of the language to specialize on. Keep in mind I am asking these questions with the genuine interest of understanding the point of view of the core devs. I want to say this before the conversation goes into the wrong direction again.

From the perspective of someone interested in math in general, it feels unnatural to have these concepts not exported by default, and instead have them defined inside of LinAlg. I think of LinAlg as implementations of these high-level concepts for array types. Perhaps my entire work does not require linear algebra on arrays, but I could still benefit from the concept of inner product across packages (e.g. MultivariateStats.jl, Clustering.jl). Also, I may not want to have LinAlg as a dependency in my package because it is not.

If I can emphasize it further, there is the concept of inner product, which is independent of arrays. This concept is represented by the statement export inner in Base. There is the implementation of inner products for array-like objects representing coordinates inner(x,y) = sum(x.*y). This operation can be defined as a fallback method in Base like above, if necessary.

Jutho commented 6 years ago

Another example of a use case is Krylov methods. If you have e.g. function spaces with inner products, then you could use Krylov methods to approximate a linear problem or eigenproblem in a small finite-dimensional subspace of that infinite dimensional function space.

I too have my own objects which form a vector/Hilbert space but are not part of <: AbstractArray. From the analogy that also arrays with rank N>1 form vector spaces and can be used as 'vectors' in Krylov methods, I've come to rely on using vecdot and vecnorm being the generalized notion of inner product and norm. So I've been developing a package with Krylov methods that uses functions as linear operators and where the 'vector's can be of any type, provided objects of that type support vecdot, vecnorm and a few other things (scale!, zero, ...). But maybe that is abusing what was meant by these concepts in Base, so it would be good to straighten out the correct interface here.

andyferris commented 6 years ago

Right - vecdot could be renamed inner.

(Now I’m vaguely wondering if norm should actually be called matrixnorm for matrices with norm always matching inner. It seems that maybe there are two distinct things going on with norm which is causing some difficulties with generalising it)

Jutho commented 6 years ago

In fact, for general vector-like objects, it's also useful to query the dimension of the vector space (e.g. to verify that Krylov dimension should not be larger than dimension of the full space in my example use case). The example of nested arrays shows that length is not the right concept here, i.e. there would need to be some recursive notion of length for those cases.

Now for the example of using nested arrays as a general vector, vecdot and vecnorm are in some cases not even the correct notion of inner product and norm, as discussed in #25093, i.e. they are not recursively calling vecdot and vecnorm. My interpretation of these functions as a generic inner product and norm function is what triggered #25093, but it seems that this might not be how these functions were intended (not sure what they were intended to do instead).

So I do agree that we need a consistent interface here to be used across packages, that would therefore belong in a central location (probably not in Base but certainly in a Standard Library, e.g. such that one has to do using VectorSpaces). As for naming, I see two options:

Option 1 (my interpretation so far): the prefix vec indicates the property of that object when interpreting it as a generic vector, hence

Option 2 (probably better): use more mathematically correct names

And finally, just pinging @stevengj as he will certainly have some useful comments; my apologies if this is inconvenient.

stevengj commented 6 years ago

The name is the least interesting part of all of this. I have zero problems with using the function dot to refer to a general inner product for arbitrary Hilbert spaces. Not only is there no other reasonable meaning for e.g. "dot product of two functions", it's pretty common to see "dot product of functions" in informal usage, especially in pedagogical settings where one is trying to emphasize the analogy to finite-dimensional vector spaces.

@juliohm, inner(x,y) = sum(x.*y) is not even an inner product in general, so this would be a pretty terrible fallback to put in to base.

Jutho commented 6 years ago

But dot is already not computing the correct inner product (in fact failing) for various objects in Base that behave as vectors, e.g. arrays with rank N>1 or nested arrays (nested vectors being the only case where it does work correctly). Furthermore, the generic name norm becomes ambiguous for matrices, because I agree with the current choice of having this return the induced norm, but occasionally the "vector norm" (Frobenius norm) is also required.

Hence, my least-impact proposal would be to let go of the semantics vecnorm(x) = norm(vec(x)) and rather interpret vecnorm(x) as "for x being an object of some generic type that behaves as a vector space, compute the corresponding vector norm of x" (and similar with vecdot). While this is a shift in interpretation (and hence documentation), the actual implementation/action for objects in Base would not be very different (PR #25093) and would produce the same result for most cases (rank N arrays of scalars or of vectors). A function veclength(x) that returns the corresponding vector space dimension of x would complete the interface.

Custom packages should then learn to implement these functions when they define new types which behave as vectors.

juliohm commented 6 years ago

it's pretty common to see "dot product of functions" in informal usage, especially in pedagogical settings where one is trying to emphasize the analogy to finite-dimensional vector spaces

Please don't say the name is unimportant, because it is. I will repeat for the n-th time: inner product and dot product are not the same thing. Any serious material exposing work with abstract Hilbert spaces will never use "dot". If you prefer to trust Wikipedia rather than my words, here are the definitions copied and pasted:

Inner product

In linear algebra, an inner product space is a vector space with an additional structure called an inner product. This additional structure associates each pair of vectors in the space with a scalar quantity known as the inner product of the vectors.

Dot product

In mathematics, the dot product or scalar product is an algebraic operation that takes two equal-length sequences of numbers (usually coordinate vectors) and returns a single number.


This resistance to improve terminology and mathematical consistency in the language is demotivating. No matter how many facts I present to you, no matter the number of examples and use cases, there is no counter argument other than "I'm fine with dot".

stevengj commented 6 years ago

@juliohm, terminology is a matter of convention, not correctness. I agree that in formal usage for Hilbert spaces, especially infinite-dimensional ones, the term "inner product" is used pretty much exclusively. But, as I said, if you google "dot product functions" you will find plenty of informal usages of that terminology too. If you say "take a dot product of two elements of this Hilbert space", every mathematician will know that you are referring to an inner product, even for infinite-dimensional spaces, so there's no real danger of confusion, because there is no other standard generalization of the term "dot product". That's why I don't find the spelling debate of "dot" vs. "inner" to be a central issue.

It is important to decide on the semantics one wants here, and the set of functions that types should implement if they define a new Hilbert space or Banach space. Currently, if you want to define a type representing a new Hilbert space, you should arguably define dot and norm (since we currently lack a fallback for the latter), and I guess adjoint if you want the mapping to a dual-space object.

As @Jutho says, this is all complicated by the array-of-arrays case, since there are multiple possible things one might want there. Since there aren't standardized names for all of the possible semantics, it's hard to find names/semantics that will satisfy everyone. See the #25093 for the discussion of vecdot semantics. I don't have a good answer here, myself.

Some possibilities here

  1. Sum of x[i]' * y[i]. Currently, this is dot(x,y). Not an inner product for vectors of matrices (where it gives a matrix), and currently not defined all for multidimensional arrays.
  2. Sum of dot(x[i], y[i]), including for multidimensional arrays, and conj(x)*y for Number. Currently, this is vecdot(x,y).
  3. Some function, e.g. inner(x,y) defined to always be a true inner product, and for arrays make it sum inner(x[i],y[i]) — essentially the "recursive vecdot" that @Jutho wants. But then, for matrices A, this inner product is inconsistent with the induced norm norm(A) that is our current norm definition. To fix it, we would have to change norm(A) for matrices to default to the Frobenius norm, which would potentially be a far-reaching breaking change.

A question (partially discussed in #25093) is whether we need all three of these in Base, or if we can get away with two (and which two, and what do we call them). @Jutho's proposal, as I understand it, is essentially to eliminate option 2 in Base and then use vecdot and vecnorm for option 3. Then we have a true inner product, but the terminology is rather unique to Julia, and a bit odd for e.g. infinite-dimensional Hilbert spaces. That wouldn't be the end of the world, of course.

Another possibility (somewhat independent of what we do with vecdot) would be to go (back) to requiring dot to be a true inner product. i.e. eliminate behavior 1, and make dot(x::AbstractVector, y::AbstractVector) equal to sum dot(x[i],y[i]). Still don't define it for multidimensional arrays (to stay consistent with norm).

stevengj commented 6 years ago

My current personal inclination would be to define dot to be a true inner product (which should be consistent with norm), changing it to sum of dot(x[i],y[i]) for vectors (i.e. changing the vector-of-matrices case), and continuing to not define it for multidimensional arrays. Then define vecdot to recursively call vecdot as @Jutho suggests, with a fallback vecdot(x,y) = dot(x,y). Finally, say that new "Hilbert-space" types should define dot and norm. This seems like the least-disruptive, most comprehensible change to me.

(A norm(x) = sqrt(real(dot(x,x))) fallback is also a possibility, although it is somewhat dangerous since it is vulnerable to spurious overflow. Note that we can't use sqrt(dot(x,x)) as the fallback for technical reasons: we want a Real result, not a Complex result.)

Jutho commented 6 years ago

Thanks @stevengj for this informative reaction. Just one small comment:

with a fallback vecdot(x,y) = dot(x,y). Finally, say that new "Hilbert-space" types should define dot and norm.

There are two problems with that. vecdot(x,y) = dot(x,y) fallback cannot exist, since vecdot does already accept Any arguments to deal with general iterators. The second problem is that, if dot and norm are exposed to be the true inner product and norm that any vector like user type should define, then even when writing a package with e.g. Krylov methods that should work with completely generic vector like types, it will still not work for the case where the user wants to use nested or multidimensional arrays as the vector like objects. Therefore, I would argue that vecdot and vecnorm are the general inner product and norm of vector like objects. This also fits nicely with the fact that for matrices, most people will indeed expect norm to be the induced matrix/operator norm.

As for an actual use case (to show that this is not some exceptional case). Stochastic matrices have a largest (Perron-Frobenius) eigenvalue for which the corresponding eigenvector represents a fixed point probability distribution. In the quantum generalization thereof, the probability distribution generalizes to a positive definite matrix (the density matrix) and such a matrix is the fixed point (eigenvector corresponding to largest eigenvalue) of a completely positive map, i.e. the map rho -> sum(A[i] rho A[i]^\dagger for i = 1:N) where thus rho is the density matrix and A[i] is a matrix for every i (known as the Kraus operators representing the completely positive map). For large matrix dimensions, an Arnoldi method is ideally suited for finding the fixed point density matrix.

juliohm commented 6 years ago

My current personal inclination would be to define dot to be a true inner product (which should be consistent with norm), changing it to sum of dot(x[i],y[i]) for vectors. Finally, say that new "Hilbert-space" types should define dot and norm.

That is a huge improvement already. Documenting dot to have inner semantics in Base will at least allow users to define their own spaces without importing unnecessary libraries. I am not happy about the naming, but at least the functionality would be available for those who need it.

andyferris commented 6 years ago

Yes, I think it will be nice to have a documented interface to implement for "Hilbert-space" types.

Of course, thinking about this generic interface for vector spaces, if it includes norm as suggested above then that should be the Frobenius norm for matrices (and generalize for higher-dimensional arrays, since all arrays are elements of a vector space). In that case we'd need a separate "operator norm" function for matrices (matnorm or opnorm or something, or a keyword argument on norm...).

Jutho commented 6 years ago

@andyferris , please note my last comment. norm and dot cannot become the general Hilbert space interface, as they don't even work on vector like objects in Julia such as higher-dimensional arrays and nested arrays. Hence vecdot and vecnorm are a 'better' (in the sense of least breaking) candidate for this.

juliohm commented 6 years ago

Reviving this topic, which I consider quite relevant to the type of math I expect to do with the language in the near future. Is there a consensus on what will be done to improve the generality and semantics of inner products?

o314 commented 6 years ago

Here is the part of my personal maths ontology concerning product. If it could help to brush up memory/ bring consensus

Bonus: no wikipedia refs

stevengj commented 6 years ago

At this point, @Jutho's proposal in #25093 seems like the least disruptive change, even though the vec* terminology is a bit odd to me in this context.

juliohm commented 6 years ago

I agree the vec* terminology is odd. That is why renaming the functions to have standard names would be beneficial to all users.

Sacha0 commented 6 years ago

I likewise agree that the vec* terminology is odd.

Jutho commented 6 years ago

I agree, as an alternative to vecdot we could introduce a new method inner, but I don't know of a good name to "replace" vecnorm. In fact, I don't find vecnorm that bad, vector norm is a well established and explicit term for the operation we want.

stevengj commented 6 years ago

The basic issue here is with matrices and multidimensional arrays, for which the usual norm(A) does not correspond to an inner product, as well as with arrays of arrays as discussed above. Some disambiguation (e.g. vec* or fro*) is required in these cases to indicate which inner product is intended.

You could have an inner function that defaults to vecdot, but it is a little silly to have two names for the same function, and there is still the problem of what to call the norm.

jebej commented 6 years ago

I also find the vecdot name odd, in fact, I didn't even know it existed and had made my own function for it... called inner.

juliohm commented 6 years ago

My understanding is that we can just deprecate the odd vecdot in favor of inner, and give it the inner product semantics for users to implement their own spaces.

Regarding the norm, that I don't know. I opened this issue to discuss inner products, maybe another issue would be appropriate to discuss the state of norms in Base.

stevengj commented 6 years ago

I suppose we could have inner(x,y) and innernorm(x) = sqrt(inner(x,x)) (with optimized special cases to avoid overflow) instead of vecdot and vecnorm. innernorm is slightly unusual but is reasonably clear in context.

juliohm commented 6 years ago

Thumbs up for this change. The names inner and innernorm are clear and consistent with the concepts. I wish they could make it to Julia v1.0.

andyferris commented 6 years ago

inner and innernorm seem OK to me.

I'd still say that, in my opinion, our norm function doesn't really fit very nicely into Julia's generic function and dispatch system and what I'd call "clear interfaces" where dispatch shouldn't be making semantic choices, just implementation choices. I'd personally rather we could say "norm returns the norm of an element of a vector space", where matrices and linear operators are still elements of vector spaces (you can add them and multiply them by a scalar). We could also have e.g. "opnorm returns the operator norm of a linear operator" (or matnorm or whatever).

At the moment we have "norm returns the norm of an element of a vector space, unless the element is also a linear operator, in which case we'll give you the operator norm instead". I personally feel that dispatch should never be surprising.

I.e. I'd prefer one function that always does vector norm and another function that always does operator norm, and no function that tries to do both.

juliohm commented 6 years ago

Like it even better @andyferris :+1: Specific norms that aren't the norms induced by the inner product in the space could have a more specific name. The name norm would mean exactly norm(x) = sqrt(inner(x,x)), and could be redefined as needed for user types.

stevengj commented 6 years ago

I'd personally rather we could say "norm returns the norm of an element of a vector space"

The current norm function satisfies that definition. For matrices, it computes the induced (operator) norm, which is a perfectly valid norm for a vector space. (Vector spaces don't have to have inner products or norms at all.)

You may be somewhat confused about the definition of a "norm" if you think that the operator norm is not a "norm of a vector space".

This is also a useful distinction between norm and innernorm. If you define norm, I would say that it implies only that you have a Banach space (or at least a normed vector space). If you define innernorm, it implies that you have a Hilbert space (or at least a inner product space) and that this norm is consistent with inner.

stevengj commented 6 years ago

For example, adaptive numerical integration (ala quadgk) is something that only requires a normed vector space, not an inner-product space.