Skip to main content
 首页 » 编程设计

python之将预定参数传递给 scipy.optimize.fsolve

2025年05月04日10leader

我正在尝试使用 Python 来求解一个包含 6 个非线性方程的系统。有 9 个变量,其中 3 个是预先确定的(留下 6 个方程组和 6 个未知数)。问题是,它可能是任何 3,我无法事先知道。

这是方程式(如果您感兴趣的话)。

c11*c12 + c21*c22 + c31*c32 = 0

c11*c13 + c21*c23 + c31*c33 = 0

c12*c13 + c22*c23 + c32*c33 = 0

c11*c21 + c12*c22 + c13*c23 = 0

c11*c31 + c12*c32 + c13*c33 = 0

c21*c31 + c22*c32 + c23*c33 = 0


注意:这是我认为最快/最容易解决的方法。另一种可能的表达方式是:

    |c11 c21 c31| 
A = |c12 c22 c32| 
    |c13 c23 c33| 
 
    |c11 c12 c13| 
B = |c21 c22 c23| 
    |c31 c32 c33| 
 
      |1 0 0| 
A*B = |0 1 0| 
      |0 0 1| 

我的问题是:是否可以将其中 3 个设置为固定参数,并让 scipy.optimize.fsolve(或更合适的模块?)求解其余参数?

请您参考如下方法:

所以,我自己找到了一个有效的解决方案。不确定它是否是最好的解决方案,但它的功能。

为了回答我的问题,scipy.optimize.fsolve 接受一个参数 args =(这里有额外的参数)。我把预定的参数放在这里。调用函数时,首先解析 args 并将 3 个预定值放在适当的位置。

其余 6 个变量在列表中传递,并迭代以填补剩余的空白。由于参数不变,每个变量始终位于矩阵中的相同位置。

使用此方法,可以预先确定任意 3 个矩阵元素,fsolve 将尝试确定余数。

fsolve 的调用语句如下所示:

paramSolve1, infodict, ier, mesg = scipy.optimize.fsolve(func,(i,i,i,i,i,i),args = (knownVals[0],knownVals[1],knownVals[2]), full_output = True, warning = False) 

knwonVals 是一个预先确定的参数列表,i 是一个起始猜测值(所有 6 个缺失的参数得到相同的起始猜测值)。 full_output 允许返回可选输出,并且 warning = False 关闭未找到解决方案时出现的警告消息。有关更多信息,请查看 http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html

对于那些感兴趣的人,问题的完整代码如下。

import scipy 
from scipy.optimize import fsolve 
 
def func(params, *args): 
    c = propMatrix(createMatrix(args), params) 
 
    ans =(scipy.dot(c[:, 0],c[:, 1]), scipy.dot(c[:, 1],c[:, 2]), scipy.dot(c[:, 0],c[:, 2]),scipy.dot(c[:, 0],c[:, 0])-1,scipy.dot(c[:, 1],c[:, 1])-1,scipy.dot(c[:, 2],c[:, 2])-1) 
    return ans 
 
def createMatrix(knownVals): 
 
    c = [['____', '____', '____'],['____', '____', '____'], ['____', '____', '____']]   
 
    for element in knownVals: 
        x, y, val = element 
        c[y][x] = float(val) 
    return c 
 
def propMatrix(c, params): 
    for p in params: 
        assign = True 
        for x in range(3): 
            for y in range(3): 
                if c[x][y]=='____' and assign: 
                    c[x][y] = float(p) 
                    assign = False 
 
    return scipy.array(c) 
 
def test(c): 
    v1 = c[:, 0] 
    v2 = c[:, 1] 
    v3 = c[:, 2] 
    h1 = c[0, :] 
    h2 = c[1, :] 
    h3 = c[2, :] 
    ans = (scipy.dot(v1,v1)-1, scipy.dot(v1,v2), scipy.dot(v1, v3), scipy.dot(v2, v2)-1, scipy.dot(v2, v3), scipy.dot(v3,v3)-1, scipy.dot(h1,h1)-1, scipy.dot(h1,h2), scipy.dot(h1, h3), scipy.dot(h2, h2)-1, scipy.dot(h2, h3), scipy.dot(h3,h3)-1) 
    return ans 
 
def getInput(): 
    knownVals = [] 
    print """\n\nThis module analytically solves for the rotation matrix\n 
    First, enter 3 known values of the matrix:\n 
                 x 
            1    2    3    
       1 | c11  c12  c13 | 
    y  2 | c21  c22  c23 | 
       3 | c31  c32  c33 |\n\n""" 
 
    for i in range(3): 
        invalid = True 
        print "Point Number %i:"%(i) 
        while invalid: 
            x = int(raw_input("\tx-coordinate:"))-1 
            if x>2 or x<0: 
                print "\tInvalid x-coordinate." 
            else: 
                invalid = False 
        invalid = True 
        while invalid: 
            y = int(raw_input("\ty-coordinate:"))-1 
            if y>2 or y<0: 
                print "\tInvalid y-coordinate." 
            else: 
                invalid = False 
        invalid = True 
        while invalid: 
            val = float(raw_input("\tValue:")) 
            if val>1 or val<-1: 
                print "\tInvalid value. Must be -1 <= value <= 1" 
            else: 
                invalid = False 
        knownVals.append((x, y, val)) 
    c = createMatrix(knownVals) 
    print "Input Matrix:\n\n", scipy.array(c) 
    choice = raw_input("\nIs this correct (y/n)?  ") 
    if choice == "y": 
        return knownVals 
    elif choice == "n": 
        return getInput() 
 
def Main(): 
    solution = False 
    knownVals = getInput() 
    for i in (-1,-.5,0,.5,1): 
        paramSolve1, infodict, ier, mesg = scipy.optimize.fsolve(func,(i,i,i,i,i,i),args = (knownVals[0],knownVals[1],knownVals[2]), full_output = True, warning = False) 
        if ier == 1: 
            print "\nInitial value: %r"%(i)  
            print propMatrix(createMatrix(knownVals),paramSolve1) 
            solution = True 
    if not solution: 
        print "Could not find a valid solution" 
 
scipy.set_printoptions(precision = 4, suppress = True) 
Main()