Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB中求解多个非线性独立方程组的最快方法?_Matlab_Performance_Equation Solving_Nonlinear Optimization - Fatal编程技术网

MATLAB中求解多个非线性独立方程组的最快方法?

MATLAB中求解多个非线性独立方程组的最快方法?,matlab,performance,equation-solving,nonlinear-optimization,Matlab,Performance,Equation Solving,Nonlinear Optimization,MATLAB有两种方法来求解非线性方程: :解一个非线性方程 :解非线性方程组 因此,可以使用以下方法来求解n非线性独立方程组: 使用循环分别使用fzero 使用循环分别使用fsolve 使用fsolve一起解决这些问题 我的直觉是: 对于大型n,循环方法比单个系统更快,因为复杂度(梯度计算)为0(n^2) 对于较小的n,循环可能较慢,因为循环在MATLAB中的开销较高,并且可能有一些恒定的启动时间 fzero比fsolve更快,因为它是专门为单个非线性方程设计的 问题:求解n非线性独立

MATLAB有两种方法来求解非线性方程:

  • :解一个非线性方程
  • :解非线性方程组
因此,可以使用以下方法来求解
n
非线性独立方程组:

  • 使用循环分别使用
    fzero
  • 使用循环分别使用
    fsolve
  • 使用
    fsolve
    一起解决这些问题
  • 我的直觉是:

    • 对于大型
      n
      ,循环方法比单个系统更快,因为复杂度(梯度计算)为0(n^2)
    • 对于较小的
      n
      ,循环可能较慢,因为循环在MATLAB中的开销较高,并且可能有一些恒定的启动时间
    • fzero
      fsolve
      更快,因为它是专门为单个非线性方程设计的
    问题:求解
    n
    非线性独立方程组的最快方法是什么?还有其他方法吗?应该使用哪些选项来加快流程

    示例问题:(可用于对不同答案进行基准测试)

    i
    介于1和
    n之间

    相关线程

    %---------------
    % ns = 10
    
    loopFZero =
    
        0.0027
    
    
    indepFSolve =
    
        0.0049
    
    
    vecBisection =
    
       5.0978e-05
    
    %---------------
    % ns = 1e5
    
    loopFZero =
    
       28.7574
    
    
    indepFSolve =
    
        7.7601
    
    
    vecBisection =
    
        0.0013
    

    评估某种方法性能的最佳方法是编写基准测试。考虑了四种情况:

  • 循环fzero:使用循环分别使用
    fzero
  • loop fsolve:使用循环分别使用
    fsolve
  • 默认fsolve:将方程作为一个方程组一起求解
  • 独立fsolve:与默认fsolve相同,但

  • 结果

    %---------------
    % ns = 10
    
    loopFZero =
    
        0.0027
    
    
    indepFSolve =
    
        0.0049
    
    
    vecBisection =
    
       5.0978e-05
    
    %---------------
    % ns = 1e5
    
    loopFZero =
    
       28.7574
    
    
    indepFSolve =
    
        7.7601
    
    
    vecBisection =
    
        0.0013
    
    所有的图都显示了整个系统在
    n
    函数中的计算时间,方程的数量

    前两个数字绘制的
    n
    最大值为1000,间隔为100。最后两个数字以1为间隔绘制100。对于每个图,第二个图与第一个图相同,但没有循环fzero,因为它比其他图慢得多

    结论

  • 循环fsolve:不要使用它,启动时间太长
  • 循环fzero:您可以将其用于较小的
    n
    (最快的
    n<~20
    )中
  • 默认fsolve:您可以将其用于相对较小的
    n
    (最快的方法是
    ~20
    ,但与2和3的差异相对较小)
  • 独立的fsolve:您应该将其用于大型
    n
    (最快的
    ~50
    方法)
  • 一般情况下,您应该使用独立的fsolve,仅对于较小的
    n
    循环,可以使用fzero,即使用
    fsolve
    和以下选项:

    options.Algorithm = 'trust-region-reflective';
    options.JacobPattern = speye(n);
    options.PrecondBandWidth = 0;
    
    懒惰的人可能只会使用默认的fsolve,因为它对中等数量的方程有合理的性能(
    n<~200

    重要评论

    Bob指出,a可能要快几个数量级。根据Bob的测试结果,他的方法对于问题的每一个大小,即大小
    n
    ,都是最快的方法

    备注

    %---------------
    % ns = 10
    
    loopFZero =
    
        0.0027
    
    
    indepFSolve =
    
        0.0049
    
    
    vecBisection =
    
       5.0978e-05
    
    %---------------
    % ns = 1e5
    
    loopFZero =
    
       28.7574
    
    
    indepFSolve =
    
        7.7601
    
    
    vecBisection =
    
        0.0013
    
    • 请注意,默认fsolve的时间复杂度为O(n^2),而其他fsolve的时间复杂度为O(n)
    • 请注意,在某些边界情况下,
      fzero
      fsolve
      的行为可能不同,f.e
      fzero
      在搜索符号更改的位置时,不会找到
      x^2
      的解决方案

      • 我添加此答案是为了详细说明我的上述评论。根据我的经验,到目前为止,最快的方法是使用文件交换上提供的fzero矢量化版本:

        这里有两个基准测试,将其性能与(i)循环fzero和(ii)独立fsolve进行比较

        f = @(x) x.^2-1; %the set of non-linear equations
        ns = 1e5; %size of the problem
        
        % method 1: looped fzero
        t = timeit(@() fzero(f, rand(1)));
        loopFZero = t*ns
        
        % method 2: independent fsolve
        options=optimset('Display','off'); % disable displaying
        options.Algorithm = 'trust-region-reflective';
        options.JacobPattern = speye(ns);
        options.PrecondBandWidth = 0;
        indepFSolve = timeit(@() fsolve(f, rand(ns,1), options))
        
        % method 3: vectorized bisection, available here:
        % https://www.mathworks.com/matlabcentral/fileexchange/28150-bisection-method-root-finding
        vecBisection = timeit(@() bisection(f, zeros(ns,1), 2))
        
        结果

        %---------------
        % ns = 10
        
        loopFZero =
        
            0.0027
        
        
        indepFSolve =
        
            0.0049
        
        
        vecBisection =
        
           5.0978e-05
        
        %---------------
        % ns = 1e5
        
        loopFZero =
        
           28.7574
        
        
        indepFSolve =
        
            7.7601
        
        
        vecBisection =
        
            0.0013
        

        在文件交换上有一个矢量化版本的fzero:根据我的经验,它比独立的fsolve(使用“JacoPattern”=speye(n)选项)强一个数量级。请审阅者注意:添加了示例问题,以便能够更好地比较不同的答案。请注意,Bob已经指出了另一种方法,它应该有自己的基准答案。不幸的是,它被mods删除了,所以我不确定是否有人能看到它。我应该重新发布吗?如果其他人看不到我下面的答案,这里有一个总结:使用与另一个答案相同的基准问题,我对
        ns=10
        的计时是:
        0.0027s
        通过循环vs
        0.0049s
        通过indep fsolve vs
        5.0978e-05s
        通过矢量化代码。对于
        ns=1e5
        我得到:
        28.7574s
        通过循环vs
        7.7601s
        通过indep fsolve vs
        0.0013s
        通过矢量化代码。@Bob,我同意重新发布答案。一、 OP,看不到你的答案。因此,几乎没有人会这么做。请注意,我在问题中明确添加了示例/基准问题。在这一行动之后,问题被重新打开(因为需要更多关注而关闭)。但是,首选的解决方案可能是标记您的答案以引起适度注意。@mods:这是我以前的答案的重新发布,该答案因不符合社区标准而被删除。我之所以重新发帖,是因为OP明确要求我这么做(见上面对他们问题的评论),而且我仍然相信我的方法比其他答案更有效,希望对其他人有用。@mods:注意,这个问题现在包含一个明确的基准问题,我接受了你的答案,因为这显然是迄今为止最好的方法。我希望它会提前