Description
Description
A simple function to compute the rank one (a.k.a. outer) product of two vectors, which would return a matrix.
I believe the current way to do this (or at least the way I do) involves explicit looping or reshape
ing and then matmul
(even worse than looping probably). I just suggest the mathematics be hidden away from a user inside the function, so they can pass two true vectors in and it will return a matrix.
Rank one updates are sufficiently common that I think we should include a specific function to accommodate this. Here is my crack at a simple "column-major-optimized" version (I'd do speed tests comparing the various methods if we want this function):
function rop(u,v) result(mat)
implicit none
real, intent(in) :: u(:), v(:)
real :: mat(size(u),size(v))
integer :: col
do col=1,size(v)
mat(:,col) = v(col) * u
end do
end function
Options/alternatives to a dedicated function:
- this functionality may eventually be provided by a more general tensor product routine (like those below), so perhaps this would just be a holdover
- something like this likely exists in BLAS somewhere in which case this function would be a wrapper for that if desired
- there could also be a good reason (that I don't) know why this feature doesn't exist, hasn't been proposed, and shouldn't be implemented (perhaps like the fact it requires quadratic storage for a linear amount of data in which case it might be preferable to update all elements in a loop instead, who knows?)
Prior Art
Numpy does not provide a rank-one-product-specific function, but provides this functionality through multiple functions, including:
numpy.outer(u,v)
numpy.tensordot(u,v,axes=0)
numpy.einsum('i,j',u,v)
ornumpy.einsum('i,j->ij',a,a)
given vectorsu
,v
.
Relevant but separate discussion
Perhaps this is just a result of my field of interest, but I'd like to bring up the discussion of terminology for the number of array dimensions (only since it's relevant here):
- I believe the current Fortran terminology is "rank", this is not optimal in my eyes because rank has a conflicting linear algebra definition (especially problematic since Fortran is commonly used for linear algebra); Python/Numpy also uses rank, but that doesn't make it "right"
-"order", "mode", or "way" are my suggestions and what many people use as an alternative to rank in literature on multi-way arrays beyond matrices - "dimension" seems to make sense but is almost ubiquitously used to describe the length of a mode, so I would say it's out of the question