• Matlib’s lsqnonlin 和 scipy.optimize’s least_square


    matlib’s lsqnonlin 和 scipy.optimize’s least_square

    问题

    有三个点 $A,B,C$ , 经过一个线性变换 $T$ , 变为了 $A’,B’,C’$ 三点,现在知道 $A,B,C$ , $A’,B’,C’$ 六个点坐标, 求出相应的变换 $T$ ?

    matlab

    matlab 使用的都是矩阵运算,所以一切在都要化成矩阵形式。直接将问题写成矩阵形式有一些不直观。所以首先将问题写成一些线性方程组的形式,根据线性方程组的形式再写出矩阵的形式。 假设

    • 线性方程组的形式 为:

    其中前两个一组两个一组,第一个和第二个方程组组成的矩阵形式为:

    将六个方程组合并成为:

    矩阵的表示形式之后,使用 MATLAB 的程序 lsqnonlin 优化程序得到 $T$ .

    lsqnonlin 的输入是要优化的函数句柄和初始参数向量 $X$ ,输出是一个结果向量。注意这里输入和输出都是向量。当要优化的变量是矩阵形式的时候,例如本例子中的 $T$ , 需要人为的将其变为向量作为参数向量传入要被 lsqnonlin 优化的函数,同样,当结果也是矩阵形式时候,也要做类似转换。

    针对上面的公式 和 分析 ,得出的 MATLAB 代码如下:

    function F = foo(T)
        T = reshape(T,3,2);
        R = [-2^0.5/2,0,2^0.5 ;
              -2^0.5/2+1,0+1,0+1;
              1,1,1];
        A = [1+3,0+3,-1+3;
            0+1,0+1,1+1];
        F = reshape(T'*R-A,1,[]); %向量化
    
    % 命令行调用函数
    lsqnonlin(@foo,ones(3,2))
    
    ans =
    
       -0.7071    0.7071
       -0.7071   -0.7071
        3.7071    1.7071
    

    由上面返回的 ans 结果可以得到 $T$ 。

    python’s scipy.optimize

    scipy 中的数值计算不同于 MATLAB ,是基于元素的 , 所以我们没必要将线性方程组化为矩阵形式 。 坐标的线性变换为 ,

    其中 $x,y$ 可以分别是列向量, 所以假设

    则可以写成

    为了方便写代码,这里将$T$ 的各个元素的顺序改变了一下。其中 x[:,[1,0]] 是将两列换一下。

    所以对应的代码为:

    In [9]: def foo1(T):
       ...:
       ...:     R = np.array([ [-2**0.5/2,0,2**0.5 ],
       ...:           [-2**0.5/2+1,0+1,0+1大专栏  Matlib’s lsqnonlin 和 scipy.optimize’s least_squaren>]]).T
       ...:     A = np.array([ [1+3,0+3,-1+3],
       ...:         [0+1,0+1,1+1]]).T
       ...:
       ...:     return np.ndarray.flatten(T[:2]*R+T[2:4]*A[:,[1,0]]+T[4:])
       ...: from scipy.optimize import least_squares as l_s
       ...: T0 = np.ones(shape=(6,))
       ...: print(l_s(foo1,T0))
       ...:
     active_mask: array([ 0.,  0.,  0.,  0.,  0.,  0.])
            cost: 6.1972286281607316e-46
             fun: array([ -2.62791580e-23,  -1.37051771e-24,   4.13590306e-24,
             0.00000000e+00,   2.27798139e-23,  -3.30872245e-24])
            grad: array([  5.07976927e-23,  -3.71013779e-24,   2.34163730e-23,
            -1.20995158e-23,   6.36559009e-25,  -4.67924016e-24])
             jac: array([[-0.70710678,  0.        ,  1.        ,  0.        ,  1.        ,
            -0.        ],
           [ 0.        ,  0.29289322, -0.        ,  4.        ,  0.        ,
             1.        ],
           [ 0.        ,  0.        ,  1.        ,  0.        ,  1.        ,
            -0.        ],
           [ 0.        ,  1.        , -0.        ,  3.        ,  0.        ,
             1.        ],
           [ 1.41421356,  0.        ,  2.        ,  0.        ,  1.        ,
            -0.        ],
           [ 0.        ,  1.        , -0.        ,  2.        ,  0.        ,
             1.        ]])
         message: '`gtol` termination condition is satisfied.'
            nfev: 3
            njev: 3
      optimality: 5.0797692652871677e-23
          status: 1
         success: True
               x: array([  4.30133919e-23,   6.61744490e-24,  -4.21862112e-23,
             3.30872245e-24,   4.63221143e-23,  -1.65436123e-23])
    

    lsqnonlin 和 least_square 的函数封装方法

    对于这两个函数的传入的要优化的函数 , 该函数的输出是一个向量 ,假设该向量为:

    则通过lsqnonlin 和least_square 之后的包裹为:

    其中 $c$ 是一个常量。

  • 相关阅读:
    移动端自适应之flexible
    iview表单验证之正则验证、函数验证
    h5获取地理坐标
    $store.getters调用不执行
    arcgisJs之底图切换插件
    使用iview 的表单组件验证 Upload 组件
    ArcGis之popup列表字段自定义
    NHibernate 错误
    让C#可以像Javascript一样操作Json
    ZooKeeper学习第八期——ZooKeeper伸缩性
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12147664.html
Copyright © 2020-2023  润新知