How to generate $\mathbb{R}^3$ vectors with a constraint on the sum?

82 Views Asked by At

I would like to solve a kind of linear equation with constraints. I think the linprog function of scipy could be a good choice but I have some difficulties to translate my problem and use this routine.

I would like to determine a set of $N$ vectors in $\mathbb{R}^3$ with random components but with a given sum.

Let's say $w_i$ are the weights and the sum of weights is 1. I have a vector of $w_i$ of length $N$. I would like to solve an equation like:

$$ \left[\begin{matrix} V_x \\ V_y \\ V_z \end{matrix}\right] = \left[\begin{matrix} v_{1,x} & v_{2,x} & \ldots & v_{N,x} \\ v_{1,y} & v_{2,y} & \ldots & v_{N,y} \\ v_{1,z} & v_{2,z} & \ldots & v_{N,z} \\ \end{matrix}\right] \times \left[\begin{matrix} \vdots \\ w_i \\ \vdots \end{matrix}\right] $$

I am looking for the $v_{i,k}$ with $i \in[1;N]$ and $k\in(x, y, z)$.

I have some difficulties to translate this and identify the corresponding matrix and vectors of the linprog function. But maybe there is a simpler solution.

In term of minimization, I can write it like this:

$$ \begin{aligned} V_x - \sum_{i=1}^N w_i v_{i, x} & = 0 \\ V_y - \sum_{i=1}^N w_i v_{i, y} & = 0 \\ V_z - \sum_{i=1}^N w_i v_{i, z} & = 0 \end{aligned} $$

1

There are 1 best solutions below

0
On BEST ANSWER

To restate your question: you are given a vector $w = (w_1,\dots,w_N) \in \Bbb R^N$ such that $\sum_{i=1}^n w_i = 1$ (and presumably $w_i \geq 0$ for all $i$), and a target vector $v = (V_x,V_y,V_z) \in \Bbb R^3$. You are looking for a "random" matrix $M \in \Bbb R^{3 \times N}$ such that $v = Mw$.

Notably, $v = Mw$ is a linear system of equations on the entries. A nice way to generate solutions (and hence generate a "random" solution) to a linear system of equations is to find a particular solution to the system and add any of the solutions to the homogeneous problem. In our case, this means we can find any matrix $M_0$ for which $M_0w = v$, generate a random matrix $H$ for which $Hw = 0$, then take $M = M_0 + H$.

One convenient "particular solution" $M_0$ is $M_0 = [v \ \ v\ \ \cdots \ \ v]$, which is intuitive if you interpret $M_0 w$ as a sort of weighted average. To generate a matrix $H$, note that $Hw = 0$ if and only if the rows of $H$ are orthogonal to $w$. With that said, if we find a matrix $B$ whose rows are a basis to the orthogonal complement of $w$, then we can take our $H$ to be $$ H = AB $$ for some random $3\times(N-1)$ vector $A$. A nice thing about this process is that every homogeneous solution $H$ can be generated in this fashion.

Here's a Python script that implements the above process:

import numpy as np
from scipy.linalg import null_space
from numpy.random import randn

N = 10
v = np.array([1,-1,3])
w = np.arange(1,N+1)
w = w/w.sum()

M0 = np.hstack([v[:,None]]*N)
B = null_space(w[None,:]).T
A = randn(3,N-1)

M = M0 + A@B

You can verify that the matrix M generated by this script is such that M@w is equal to v. Note that the only "random" part of the above script is the matrix A.