使用numpy求解具有一个未知数的线性系统?

时间:2019-01-10 16:20:09

标签: python numpy math matrix linear-algebra

我正在尝试以编程方式解决一个非常简单的问题。

我有一个变量t,必须同时满足两个方程,如下所示:

x_v*t = (x_1 - x_2)
y_v*t = (y_1 - y_2)

我的第一个反应是通过将右侧除以左侧的系数来解决该问题,但是不能保证该系数不为0。

因此,我们始终可以使用RREF算法并将系统表示为:

 a | b
 c | d

其中a = x_v,b =(x_1-x_2),c = y_v,d =(y_1-y_2)

找到RREF之后,我们可以得到:

  • 0矩阵(系统可解)
  • 第一行有一个前导行,第二行是0(系统可存储)
  • 每一行的前导数字为0,尾随数字为非零(系统无法求解)

尽管我可以尝试自己编写上述代码,但我想使用一个库代替我可以在那里设置系统并询问api是否存在解决方案的库,所以我使用了numpy。

但是,目前我什至无法设置非扩展矩阵不是正方形的系统。

这可以实现吗?

2 个答案:

答案 0 :(得分:1)

这是可以实现的。您可以使用fsolve库的函数scipy。一个例子

    func saveImageToAlbum(_ image: UIImage, name: String) {

        if let collection = fetchAssetCollection(name) {
            self.saveImageToAssetCollection(image, collection: collection)
        } else {
            // Album does not exist, create it and attempt to save the image
            PHPhotoLibrary.shared().performChanges({
                PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: name)
            }, completionHandler: { (success: Bool, error: Error?) in
                guard success == true && error == nil else {
                    NSLog("Could not create the album")
                    if let err = error {
                        NSLog("Error: \(err)")
                    }
                    return
                }

                if let newCollection = self.fetchAssetCollection(name) {
                    self.saveImageToAssetCollection(image, collection: newCollection)
                }
            })
        }
    }

    func fetchAssetCollection(_ name: String) -> PHAssetCollection? {

        let fetchOption = PHFetchOptions()
        fetchOption.predicate = NSPredicate(format: "title == '" + name + "'")

        let fetchResult = PHAssetCollection.fetchAssetCollections(
            with: PHAssetCollectionType.album,
            subtype: PHAssetCollectionSubtype.albumRegular,
            options: fetchOption)

        return fetchResult.firstObject
    }

    func saveImageToAssetCollection(_ image: UIImage, collection: PHAssetCollection) {

        PHPhotoLibrary.shared().performChanges({

            let creationRequest = PHAssetCreationRequest.creationRequestForAsset(from: image)
            if let request = PHAssetCollectionChangeRequest(for: collection),
                let placeHolder = creationRequest.placeholderForCreatedAsset {
                request.addAssets([placeHolder] as NSFastEnumeration)
            }
        }, completionHandler: { (success: Bool, error: Error?) in
            guard success == true && error == nil else {
                NSLog("Could not save the image")
                if let err = error {
                    NSLog("Error: " + err.localizedDescription)
                }
                return
            }
        })
    }

然后您会做

import numpy as np
import scipy.optimize as so

def f(t, x_v, x_1, x_2, y_v, y_1, y_2):
    return np.sum(np.abs([
        x_v*t - (x_1 - x_2),
        y_v*t - (y_1 - y_2),
    ]))

输出

sol_object = so.fsolve(
    func = f,                  # the function that returns the (scalar) 0 you want. 
    x0   = 1,                  # The starting estimate
    args = (1, 2, 3, 1, 2, 3), # Other arguments of f, i.e. x_v, x_1, x_2, y_v, y_1, y_2 
    full_output = True
)
sol        = sol_object[0]
message    = sol_object[-1]

print(sol)
print(message)


正如jdhesa的评论中提到的那样,可以使用线性参数求解方法来完成此操作。我在先验上面使用的那个可以进行任何形式的转换。

答案 1 :(得分:0)

另一种方法是只执行除法。 如果两个“边”均为零,则结果将为NaN(0/0)。 如果rhs即(x_1-x_2)不为零,则结果为inf。

# c1 is np.array([x_1, y_1, z_1, ...])
# c2 is np.array([x_2, y_2, z_2, ...])
c = c1 - c2
# Use this to supress numpy warnings
with np.warnings.catch_warnings():
    np.warnings.filterwarnings('ignore', 'invalid value encountered in true_divide')
    np.warnings.filterwarnings('ignore','divide by zero encountered in true_divide')
    t = c / v
non_nan_t = t[~np.isnan(t)]
if np.isinf(t).any():
    print('unsolvable because rhs is nonzero but v is zero')

elif not np.allclose(non_nan_t, non_nan_t[0]):
    print('no solution because equations disagree')
else:
    print('solution:', non_nan_t[0])