Re: Feature proposal: weighted gram matrix / sandwich product

Christian Lorentzen via NumPy-Discussion <[email protected]>
Newsgroups gmane.comp.python.numeric.general
Message-ID <[email protected]>
If W is just a vector, i.e. my main use case, than what you write is 
what I wanted to imply and actually how I implemented it in several cases.
The point is that X.T * weights[None, :] still doubles memory (same size 
as X) and this solution doesn't exploit the symmetry.

Best
Christian

On 17.08.2025 22:13, Kevin Jacobs wrote:
> Why not:
>
> XTWX = (X.T * weights[None, :]) @ X
>
> if `weights` is a vector?  Allocating `diag(weights)` is the big 
> memory and CPU hog at least for my generally long and skinny X matrices.
>
> -Kevin
>
>
> On Fri, Aug 15, 2025 at 10:08 AM Christian Lorentzen via 
> NumPy-Discussion <[email protected]> wrote:
>
>     Dear numpy community
>
>     I would like to propose a mew feature in np.linalg to compute
>     weighted gram matrix (sandwich product), see
>     https://github.com/numpy/numpy/issues/29559.
>
>
>           Proposed new feature or change:
>
>     The solvers for many important statistical models like Generalized
>     Linear Models often need to compute |X.T @ W @ X| where |X| is a
>     2-dimensional array of features (features in columns, observations
>     in rows) and |W| is very often a diagonal array of (current)
>     weights. This computation is usually the main computational
>     bottleneck.
>
>     It would be great if numpy could provide an efficient
>     implementation of it, e.g. |np.linalg.sandwicht_product(X, weight=w)|.
>
>     Why numpy? It seems even more unrealistic to me, to get it into
>     BLAS implementations. Numpy has support for SIMD via Highways.
>
>
>             Computational alternatives
>
>     Drawbacks of |(X.T * diag(W)) @ X|:
>
>       * Additional memory allocation to compute |X.T @ diag(W)| , same
>         size as (usually large) |X|.
>       * The result is symmetric, but this fact is not used. So at
>         least a factor of 2 is possible.
>         Note that without weights, |X.T @ X| uses BLAS syrk. But the
>         weights are crucial.
>
>     Drawback of |Z = np.sqrt(diag(W))[:, None] * X| and then |Z @ Z|:
>
>       * Additional memory allocation for |Z|, same size as (usually
>         large) |X|.
>       * Taking square roots for possibly large |diag(W)|
>
>
>           Additional information
>
>     https://github.com/Quantco/tabmat has an implementation of it with
>     XSIMD.
>
>
>     Best
>     Christian Lorentzen
>
>     _______________________________________________
>     NumPy-Discussion mailing list -- [email protected]
>     To unsubscribe send an email to [email protected]
>     https://mail.python.org/mailman3//lists/numpy-discussion.python.org
>     Member address: [email protected]
>
>
> _______________________________________________
> NumPy-Discussion mailing list [email protected]
> To unsubscribe send an email [email protected]
> https://mail.python.org/mailman3//lists/numpy-discussion.python.org
> Member address:[email protected]

_______________________________________________
NumPy-Discussion mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.