MeasureTheory.jl icon indicating copy to clipboard operation
MeasureTheory.jl copied to clipboard

Overload LinearAlgebra.cross for ProductMeasure

Open sethaxen opened this issue 5 years ago • 13 comments

This package defines ×(μ::AbstractMeasure{X}, ν::AbstractMeasure{Y}). This will collide with LinearAlgebra.cross, which is aliased to ×, which is exported. The solution we used in Manifolds.jl was to overload LinearAlgebra.cross and then re-export ×.

sethaxen avatar Oct 02 '20 18:10 sethaxen

Could we use the classical ?

mschauer avatar Oct 02 '20 18:10 mschauer

We should probably use whatever the standard notation is for product measures (I don't know what that is). I also feel strongly that unicode symbols as operators should only be convenient aliases of functions with descriptive names (among other things, having non-unicode function names makes it easier for other languages with less unicode support to interop with the package).

sethaxen avatar Oct 02 '20 19:10 sethaxen

Thanks for catching this, @sethaxen .

I also feel strongly that unicode symbols as operators should only be convenient aliases of functions with descriptive names (among other things, having non-unicode function names makes it easier for other languages with less unicode support to interop with the package).

This is ProductMeasure, which has Base.* as shorthand. @mschauer makes a great point here, I think is more common in this context. I'm sure we'll have the same issue, since other libraries use , but I guess we can just figure that out as we go.

cscherrer avatar Oct 02 '20 21:10 cscherrer

I am against using LinearAlgebra.cross. The measure product is isn't a cross product at all, and I don't usually think of measures as elements of a vector space (that works for signed measures only, IIRC?). I believe the measure product is much closer to a tensor product -- induced by a pairing operation on the underlying spaces.

As for the notation, I prefer \otimes, but I'm not completely against \times either.

phipsgabler avatar Oct 03 '20 07:10 phipsgabler

× and * can easily be confused with products of random variables, that is one reason

mschauer avatar Oct 03 '20 07:10 mschauer

@phipsgabler As I understand, the only reason @sethaxen metioned overloading LinearAlgebra.cross was to more easily allow overloading of \times. But as you and @mschauer point out, \otimes is probably more appropriate here anyway, so I think the point about cross is now moot.

I've also been using * for this, because it's literally a product of measures (in the category-theoretic sense) and distributes over superposition. But I haven't thought further about it than this. Does it make sense to take polynomials over a measure? What about exp(μ)? I don't see it yet.

cscherrer avatar Oct 03 '20 14:10 cscherrer

Hmm... I may have jumped the gun on this - I'm seeing a fair number of texts using \times, for example https://terrytao.files.wordpress.com/2011/01/measure-book1.pdf

@mschauer do you see a particular context where \otimes is more common? There's no rush on this, but we'll need to nail down the notation at some point.

cscherrer avatar Oct 10 '20 21:10 cscherrer

I think majority of the literature uses ⊗ but × is of course also reasonable. The reason for ⊗ is that the cartesian product of sigma fields 𝔉 × 𝔅 is not a sigma field yes and one defines 𝔉 ⊗ 𝔅 = σ(𝔉 × 𝔅) as the completion. And then it is very natural to also call the product measure by ⊗, because it also doesn't only measure the elements of 𝔉 × 𝔅 but all of 𝔉 ⊗ 𝔅.

mschauer avatar Oct 10 '20 21:10 mschauer

I would suggest implementing TensorCore.tensor for product measures and reexport both TensorCore.tensor and its alias TensorCore.:⊗. This would allow to construct product measures both with the unicode operator and its alias tensor. TensorCore is a lightweight package that contains default implementations for tensor operations. Originally, the code was merged in https://github.com/JuliaLang/julia/pull/35150 which was later reverted in https://github.com/JuliaLang/julia/pull/35744 and moved to its own package. It will be implemented in KernelFunctions such that users can construct tensor product kernels in a more convenient way (https://github.com/JuliaGaussianProcesses/KernelFunctions.jl/pull/232).

devmotion avatar Jan 18 '21 12:01 devmotion

Thanks @devmotion . Between × and ⊗, I think issues are

×

The semantics here are fundamentally different than LinearAlgebra.cross. I'd guess that being exported invalidates its use in lots of cases, and the real solution is probably for LinearAlgebra to not export the symbol, to allow its use in other contexts.

This seems pretty good, and I mostly like the idea of extending a lightweight package.

In addition to pairs, we'll often store the data for a ProductMeasure in an array. In particular, a MappedArray corresponds to Soss's For, and a FillArray is like iid. And it seems to work out, because we could just have

⊗(μ::ProductMeasure, ν::ProductMeasure) = ProductMeasure(μ.data ⊗ ν.data)

But this makes me think we could benefit from a more efficient implementation, for example https://github.com/MichielStock/Kronecker.jl

cscherrer avatar Jan 18 '21 14:01 cscherrer

OTOH this is wrong; the notation here gets very tricky

The product of two univariate measure is bivariate, so the dimensions add. So the operation on the support is a (standard) product, not a Kronecker product.

But it is bilinear, if we consider weighted measure as scalar multiplication and superposition as addition.

cscherrer avatar Jan 18 '21 14:01 cscherrer

I am more used to the notation ⊗ than × and agree with the explanation given by @mschauer above, therefore personally I would rather implement TensorCore.:⊗ than LinearAlgebra.:×.

Apart from that, I don't understand why the implementation should be problematic in any of these cases. There is nothing wrong with LinearAlgebra defining ×, you can just extend it for the types you own (such as ProductMeasure or whatever) in the same way as you can extend any function from Base. The same can be done with TensorCore.:⊗. You don't have to use or fall back to any of the default implementations in LinearAlgebra and TensorCore; e.g., in KernelFunctions we never use any array-related functionality in TensorCore. The only problem with the unicode operators is if packages start to define and export them (such as MeasureTheory or Kronecker...) even though the names are so generic that they should either be defined in Base, one of the standard libraries, or a lightweight interface such as TensorCore.

devmotion avatar Jan 18 '21 14:01 devmotion

There is something like "name piracy". If print(a) doesn't give a method error, it is really expected to print, even if you own the type of A. So that is against ×.

mschauer avatar Jan 18 '21 19:01 mschauer