How can I solve a system of x*y = c, where x and c are vectors, and y is a matrix in python?

huangapple go评论65阅读模式
英文:

How can I solve a system of x*y = c, where x and c are vectors, and y is a matrix in python?

问题

我有一个问题,我有一个向量"c",我知道它的值,大小为100,我希望我的代码能够找到一个大小为30的向量"x"和一个大小为(30,100)的矩阵"y",使得x*y= c,而"x"和"y"的范数最小。

我想知道算法,这样我就可以对任何c进行操作或更改向量和矩阵的维度。

我尝试过使用sympy和linalg.lstsq,但据我所见,它们都不能同时解决x和y的问题。我尝试了一种方法,通过使用一个种子使x成为随机值,但这是我想要避免的,因为我想要的是一种可以根据用户提供的数据调整x和y的方法,不依赖于不来自用户的数据(或者我将不得不为每个用户提供唯一的种子)。

谢谢您的帮助。

英文:

I have a problem where I have a vector "c" which I know its values and it size is 100, and I want my code to find a vector "x" of size 30 and a matrix "y" of size (30,100), so that x*y= c and the norm of "x" and "y" are minimal.
I want to know the algorithm, so that I can do this for any c or change the dimensions of the vectors and matrices.

I tried using sympy and linalg.lstsq, but as far as I saw, both don't solve the problem for x and y at the same time. And tried one approach by making x to be random with a seed, but that is something I want to avoid since what I want is a method that adjust both x and y from a data given by the user and don't depend on data that doesn't come from the user (or I'll will have to give unique seeds for each user).

Thanks for your help

答案1

得分: 1

你似乎在寻找矩阵的伪逆。NumPy可以通过linalg.pinv来处理这些。

然而,如果你期望得到x的唯一解,你应该记住y的矩阵秩最多为30。换句话说,你不能在你的100维向量空间和30维向量空间之间建立双射。

但是,如果你对编写伪逆的代码感兴趣,你可以编写类似以下的代码:

import numpy as np

c = np.random.rand(100)
y = np.random.rand(30,100)

x = c.dot(np.linalg.pinv(y))
英文:

You seem to be looking for the pseudo-inverse of the matrix. NumPy can handle those with linalg.pinv.

However, if you're expecting to get a unique answer for x, you should keep in mind that the matrix rank of y is at most 30. In other words, you can't have a bijection between the spaces of your 100-dimensional vectors and your 30-dimensional vectors.

Still, if you're interested in coding in the pseudo-inverses, you can write something like :

import numpy as np

c = np.random.rand(100)
y = np.random.rand(30,100)

x = c.dot(np.linalg.pinv(y))

答案2

得分: 0

I can help you with the translation of the code portion:

我可以帮你翻译代码部分

def optimize(c, layerSize):
    def objective(x):
        n = len(x)
        dist_sum = 0
        for i in range(n):
            for j in range(i+1, n):
                dist_sum += np.abs(x[i] - x[j])
        return -dist_sum  # 优化目标是使得'x'中的元素彼此不同

    def constraint(x, c):
        return np.linalg.norm(x) - np.sqrt(np.linalg.norm(c)) #

    # x的初始值
    initial_guess = np.zeros(layerSize)

    # 定义优化问题
    problem = {
        'type': 'eq',
        'fun': constraint,
        'args': (c,)
    }

    # 解决优化问题
    solution = minimize(objective, initial_guess, constraints=problem)

    # 找到最优向量x
    x_opt = solution.x
    y_opt = resolve(x_opt, c)
    
    return x_opt, y_opt

然后使用另一个优化问题从向量x和c中找到y_opt

```python
def resolve(x_opt, c):
    # 维度
    n = len(x_opt)
    d = len(c)

    def objective2(y):
        return np.linalg.norm(y)

    # y的初始值
    initial_guess2 = np.zeros((n, d))

    # 定义优化问题
    problem2 = {
        'type': 'eq',
        'fun': lambda y: np.dot(x_opt, y.reshape((n, d))).flatten() - c
    }

    # 解决优化问题
    solution = minimize(objective2, initial_guess2, constraints=problem2)

    # 找到最优矩阵y
    y_opt = solution.x.reshape((n, d))
    return y_opt

希望这有所帮助!如果您有其他问题,请随时提问。

英文:

Well, I got a solution for the problem from here:
Solving least-norm problem with Bilinear constraints

Using the equation of ||a||= squared root of ||c||, I can use this to solve an optimization problem for vector x

def optimize(c,layerSize):
    def objective(x):
      n = len(x)
      dist_sum = 0
      for i in range(n):
          for j in range(i+1, n):
              dist_sum += np.abs(x[i] - x[j])
      return -dist_sum  # Objetive to make elements of 'x' different between them

    def constraint(x, c):
      return np.linalg.norm(x) - np.sqrt(np.linalg.norm(c)) #

    # Initial values for x
    initial_guess = np.zeros(layerSize)

    # Define Optimization problem
    problem = {
        'type': 'eq',
        'fun': constraint,
        'args': (c,)
    }

    # Resolve optimization problem
    solution = minimize(objective, initial_guess, constraints=problem)

    # Find optimal vector x
    x_opt = solution.x
    y_opt = resolve(x_opt,c)
    
    return x_opt,y_opt

Then use another optimization problem to find y_opt from vector x and c

def resolve(x_opt,c):
    # Dimensions
    n = len(x_opt)
    d = len(c)

    def objective2(y):
        return np.linalg.norm(y)

    # Initial values for y
    initial_guess2 = np.zeros((n,d))

    # Define optimization problem
    problem2 = {
        'type': 'eq',
        'fun': lambda y: np.dot(x_opt, y.reshape((n, d))).flatten() - c
    }

    # Resolve Optimization problem
    solution = minimize(objective2, initial_guess2, constraints=problem2)

    # Find optimal matrix y
    y_opt = solution.x.reshape((n, d))
    return y_opt

With these, given a vector c, you can find a vector 'x' and a matrix 'y' that satisfy the system, the resolve function is to avoid the round errors of the computation of 'x', otherwise you can compute y_opt using the equation given in the post

huangapple
  • 本文由 发表于 2023年5月13日 09:19:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76240696.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定