最小二乗法(least squares method)

永井 忠一 2024.11.3


直線のあてはめ(fitting)

二乗和誤差(sum-of-squares error)を最小化する\[ J(a, b) = \sum_{i = 0}^{N-1} \left( y_i - (a x_i + b) \right)^2 \rightarrow \min \]係数 a, b を求める

評価関数(誤差関数) J を、係数ベクトル \( \begin{pmatrix} a \\ b \end{pmatrix} \) で微分(偏微分)して 0 になるとして、(連立方程式を)解く\[ \begin{gather} \frac{\partial J(a, b)}{\partial a} = 0, \quad \frac{\partial J(a, b)}{\partial b} = 0 \end{gather} \]

M 次多項式(一般の場合)として、連立一次方程式を解いた例 → 以前のページ

Maxima を使って解く

(Maxima で記号計算)

データ点数 N = 10 の場合

Maxima
$ maxima

Maxima 5.46.0 https://maxima.sourceforge.io
using Lisp GNU Common Lisp (GCL) GCL 2.6.14 git tag Version_2_6_15pre7
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.

(%i1) solve([diff(sum((y[i] - (a*x[i] + b))^2, i, 0, 9), a) = 0, diff(sum((y[i] - (a*x[i] + b))^2, i, 0, 9), b) = 0], [a, b]);
(%o1) [[a = ((9 x  - x  - x  - x  - x  - x  - x  - x  - x  - x ) y
                 9    8    7    6    5    4    3    2    1    0   9
 + ((- y ) - y  - y  - y  - y  - y  - y  - y  - y ) x
        8     7    6    5    4    3    2    1    0   9
 + (9 x  - x  - x  - x  - x  - x  - x  - x  - x ) y
       8    7    6    5    4    3    2    1    0   8
 + ((- y ) - y  - y  - y  - y  - y  - y  - y ) x
        7     6    5    4    3    2    1    0   8
 + (9 x  - x  - x  - x  - x  - x  - x  - x ) y
       7    6    5    4    3    2    1    0   7
 + ((- y ) - y  - y  - y  - y  - y  - y ) x
        6     5    4    3    2    1    0   7
 + (9 x  - x  - x  - x  - x  - x  - x ) y
       6    5    4    3    2    1    0   6
 + ((- y ) - y  - y  - y  - y  - y ) x  + (9 x  - x  - x  - x  - x  - x ) y
        5     4    3    2    1    0   6       5    4    3    2    1    0   5
 + ((- y ) - y  - y  - y  - y ) x  + (9 x  - x  - x  - x  - x ) y
        4     3    2    1    0   5       4    3    2    1    0   4
 + ((- y ) - y  - y  - y ) x  + (9 x  - x  - x  - x ) y
        3     2    1    0   4       3    2    1    0   3
 + ((- y ) - y  - y ) x  + (9 x  - x  - x ) y  + ((- y ) - y ) x
        2     1    0   3       2    1    0   2        1     0   2
                                         2
 + (9 x  - x ) y  - y  x  + 9 x  y )/(9 x
       1    0   1    0  1      0  0      9
                                                                              2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          8       7      6      5      4      3      2      1      0   9      8
                                                                       2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          7       6      5      4      3      2      1      0   8      7
                                                                2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          6       5      4      3      2      1      0   7      6
                                                         2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          5       4      3      2      1      0   6      5
                                                  2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          4       3      2      1      0   5      4
                                           2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x ) x  + 9 x  + ((- 2 x ) - 2 x  - 2 x ) x
          3       2      1      0   4      3          2       1      0   3
      2                             2                2
 + 9 x  + ((- 2 x ) - 2 x ) x  + 9 x  - 2 x  x  + 9 x ), 
      2          1       0   2      1      0  1      0
                                                           2    2    2    2
b = - (((x  + x  + x  + x  + x  + x  + x  + x  + x ) x  - x  - x  - x  - x
          8    7    6    5    4    3    2    1    0   9    8    7    6    5
    2    2    2    2    2
 - x  - x  - x  - x  - x ) y  + ((- y ) - y  - y  - y  - y  - y  - y  - y
    4    3    2    1    0   9        8     7    6    5    4    3    2    1
        2
 - y ) x  + (x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y
    0   9     8  8    7  7    6  6    5  5    4  4    3  3    2  2    1  1
                                                              2    2    2    2
 + x  y ) x  + ((x  + x  + x  + x  + x  + x  + x  + x ) x  - x  - x  - x  - x
    0  0   9      7    6    5    4    3    2    1    0   8    7    6    5    4
    2    2    2    2                                                    2
 - x  - x  - x  - x ) y  + ((- y ) - y  - y  - y  - y  - y  - y  - y ) x
    3    2    1    0   8        7     6    5    4    3    2    1    0   8
 + (x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y ) x
     7  7    6  6    5  5    4  4    3  3    2  2    1  1    0  0   8
                                             2    2    2    2    2    2    2
 + ((x  + x  + x  + x  + x  + x  + x ) x  - x  - x  - x  - x  - x  - x  - x )
      6    5    4    3    2    1    0   7    6    5    4    3    2    1    0
                                              2
 y  + ((- y ) - y  - y  - y  - y  - y  - y ) x
  7        6     5    4    3    2    1    0   7
 + (x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y ) x
     6  6    5  5    4  4    3  3    2  2    1  1    0  0   7
                                        2    2    2    2    2    2
 + ((x  + x  + x  + x  + x  + x ) x  - x  - x  - x  - x  - x  - x ) y
      5    4    3    2    1    0   6    5    4    3    2    1    0   6
                                      2
 + ((- y ) - y  - y  - y  - y  - y ) x
        5     4    3    2    1    0   6
 + (x  y  + x  y  + x  y  + x  y  + x  y  + x  y ) x
     5  5    4  4    3  3    2  2    1  1    0  0   6
                                   2    2    2    2    2
 + ((x  + x  + x  + x  + x ) x  - x  - x  - x  - x  - x ) y
      4    3    2    1    0   5    4    3    2    1    0   5
                                 2
 + ((- y ) - y  - y  - y  - y ) x  + (x  y  + x  y  + x  y  + x  y  + x  y ) x
        4     3    2    1    0   5     4  4    3  3    2  2    1  1    0  0   5
                              2    2    2    2                                2
 + ((x  + x  + x  + x ) x  - x  - x  - x  - x ) y  + ((- y ) - y  - y  - y ) x
      3    2    1    0   4    3    2    1    0   4        3     2    1    0   4
                                                              2    2    2
 + (x  y  + x  y  + x  y  + x  y ) x  + ((x  + x  + x ) x  - x  - x  - x ) y
     3  3    2  2    1  1    0  0   4      2    1    0   3    2    1    0   3
                       2
 + ((- y ) - y  - y ) x  + (x  y  + x  y  + x  y ) x
        2     1    0   3     2  2    1  1    0  0   3
                    2    2                      2
 + ((x  + x ) x  - x  - x ) y  + ((- y ) - y ) x  + (x  y  + x  y ) x
      1    0   2    1    0   2        1     0   2     1  1    0  0   2
             2           2                 2
 + (x  x  - x ) y  - y  x  + x  y  x )/(9 x
     0  1    0   1    0  1    0  0  1      9
                                                                              2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          8       7      6      5      4      3      2      1      0   9      8
                                                                       2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          7       6      5      4      3      2      1      0   8      7
                                                                2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          6       5      4      3      2      1      0   7      6
                                                         2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          5       4      3      2      1      0   6      5
                                                  2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x  - 2 x ) x  + 9 x
          4       3      2      1      0   5      4
                                           2
 + ((- 2 x ) - 2 x  - 2 x  - 2 x ) x  + 9 x  + ((- 2 x ) - 2 x  - 2 x ) x
          3       2      1      0   4      3          2       1      0   3
      2                             2                2
 + 9 x  + ((- 2 x ) - 2 x ) x  + 9 x  - 2 x  x  + 9 x )]]
      2          1       0   2      1      0  1      0

(%i2) fortran(%th(1)[1][1]);
      a = ((9*x[9]-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[9]+((
     1   -y[8])-y[7]-y[6]-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[9]+(9*x[8]-x[
     2   7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[8]+((-y[7])-y[6]-y[5]-
     3   y[4]-y[3]-y[2]-y[1]-y[0])*x[8]+(9*x[7]-x[6]-x[5]-x[4]-x[3]-x[2]
     4   -x[1]-x[0])*y[7]+((-y[6])-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[7]+(
     5   9*x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[6]+((-y[5])-y[4]-y[3]-y
     6   [2]-y[1]-y[0])*x[6]+(9*x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[5]+((-y
     7   [4])-y[3]-y[2]-y[1]-y[0])*x[5]+(9*x[4]-x[3]-x[2]-x[1]-x[0])*y[4
     8   ]+((-y[3])-y[2]-y[1]-y[0])*x[4]+(9*x[3]-x[2]-x[1]-x[0])*y[3]+((
     9   -y[2])-y[1]-y[0])*x[3]+(9*x[2]-x[1]-x[0])*y[2]+((-y[1])-y[0])*x
     :   [2]+(9*x[1]-x[0])*y[1]-y[0]*x[1]+9*x[0]*y[0])/(9*x[9]**2+((-2*x
     ;   [8])-2*x[7]-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x
     <   [9]+9*x[8]**2+((-2*x[7])-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x
     =   [1]-2*x[0])*x[8]+9*x[7]**2+((-2*x[6])-2*x[5]-2*x[4]-2*x[3]-2*x[
     >   2]-2*x[1]-2*x[0])*x[7]+9*x[6]**2+((-2*x[5])-2*x[4]-2*x[3]-2*x[2
     ?   ]-2*x[1]-2*x[0])*x[6]+9*x[5]**2+((-2*x[4])-2*x[3]-2*x[2]-2*x[1]
     @   -2*x[0])*x[5]+9*x[4]**2+((-2*x[3])-2*x[2]-2*x[1]-2*x[0])*x[4]+9
     1   *x[3]**2+((-2*x[2])-2*x[1]-2*x[0])*x[3]+9*x[2]**2+((-2*x[1])-2*
     2   x[0])*x[2]+9*x[1]**2-2*x[0]*x[1]+9*x[0]**2)
(%o2)                                done

(%i3) fortran(%th(2)[1][2]);
      b = -(((x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0])*x[9]-x[8]**2
     1   -x[7]**2-x[6]**2-x[5]**2-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**
     2   2)*y[9]+((-y[8])-y[7]-y[6]-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[9]*
     3   *2+(x[8]*y[8]+x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]
     4   +x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[9]+((x[7]+x[6]+x[5]+x[4]+x[3]
     5   +x[2]+x[1]+x[0])*x[8]-x[7]**2-x[6]**2-x[5]**2-x[4]**2-x[3]**2-x
     6   [2]**2-x[1]**2-x[0]**2)*y[8]+((-y[7])-y[6]-y[5]-y[4]-y[3]-y[2]-
     7   y[1]-y[0])*x[8]**2+(x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3
     8   ]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[8]+((x[6]+x[5]+x[4]+x[3
     9   ]+x[2]+x[1]+x[0])*x[7]-x[6]**2-x[5]**2-x[4]**2-x[3]**2-x[2]**2-
     :   x[1]**2-x[0]**2)*y[7]+((-y[6])-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x
     ;   [7]**2+(x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*
     <   y[1]+x[0]*y[0])*x[7]+((x[5]+x[4]+x[3]+x[2]+x[1]+x[0])*x[6]-x[5]
     =   **2-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[6]+((-y[5])-y[4]
     >   -y[3]-y[2]-y[1]-y[0])*x[6]**2+(x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[
     ?   2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[6]+((x[4]+x[3]+x[2]+x[1]+x[0])*x
     @   [5]-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[5]+((-y[4])-y[3]
     1   -y[2]-y[1]-y[0])*x[5]**2+(x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[
     2   1]+x[0]*y[0])*x[5]+((x[3]+x[2]+x[1]+x[0])*x[4]-x[3]**2-x[2]**2-
     3   x[1]**2-x[0]**2)*y[4]+((-y[3])-y[2]-y[1]-y[0])*x[4]**2+(x[3]*y[
     4   3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[4]+((x[2]+x[1]+x[0])*x[3]-x
     5   [2]**2-x[1]**2-x[0]**2)*y[3]+((-y[2])-y[1]-y[0])*x[3]**2+(x[2]*
     6   y[2]+x[1]*y[1]+x[0]*y[0])*x[3]+((x[1]+x[0])*x[2]-x[1]**2-x[0]**
     7   2)*y[2]+((-y[1])-y[0])*x[2]**2+(x[1]*y[1]+x[0]*y[0])*x[2]+(x[0]
     8   *x[1]-x[0]**2)*y[1]-y[0]*x[1]**2+x[0]*y[0]*x[1])/(9*x[9]**2+((-
     9   2*x[8])-2*x[7]-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0]
     :   )*x[9]+9*x[8]**2+((-2*x[7])-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-
     ;   2*x[1]-2*x[0])*x[8]+9*x[7]**2+((-2*x[6])-2*x[5]-2*x[4]-2*x[3]-2
     <   *x[2]-2*x[1]-2*x[0])*x[7]+9*x[6]**2+((-2*x[5])-2*x[4]-2*x[3]-2*
     =   x[2]-2*x[1]-2*x[0])*x[6]+9*x[5]**2+((-2*x[4])-2*x[3]-2*x[2]-2*x
     >   [1]-2*x[0])*x[5]+9*x[4]**2+((-2*x[3])-2*x[2]-2*x[1]-2*x[0])*x[4
     ?   ]+9*x[3]**2+((-2*x[2])-2*x[1]-2*x[0])*x[3]+9*x[2]**2+((-2*x[1])
     @   -2*x[0])*x[2]+9*x[1]**2-2*x[0]*x[1]+9*x[0]**2)
(%o3)                                done

解を確認

Python
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

# test data
x = [0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306]
y = [-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183]

# solution
a = ((9*x[9]-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[9]+((-y[8])-y[7]-y[6]-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[9]+(9*x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[8]+((-y[7])-y[6]-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[8]+(9*x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[7]+((-y[6])-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[7]+(9*x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[6]+((-y[5])-y[4]-y[3]-y[2]-y[1]-y[0])*x[6]+(9*x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*y[5]+((-y[4])-y[3]-y[2]-y[1]-y[0])*x[5]+(9*x[4]-x[3]-x[2]-x[1]-x[0])*y[4]+((-y[3])-y[2]-y[1]-y[0])*x[4]+(9*x[3]-x[2]-x[1]-x[0])*y[3]+((-y[2])-y[1]-y[0])*x[3]+(9*x[2]-x[1]-x[0])*y[2]+((-y[1])-y[0])*x[2]+(9*x[1]-x[0])*y[1]-y[0]*x[1]+9*x[0]*y[0])/(9*x[9]**2+((-2*x[8])-2*x[7]-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[9]+9*x[8]**2+((-2*x[7])-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[8]+9*x[7]**2+((-2*x[6])-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[7]+9*x[6]**2+((-2*x[5])-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[6]+9*x[5]**2+((-2*x[4])-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[5]+9*x[4]**2+((-2*x[3])-2*x[2]-2*x[1]-2*x[0])*x[4]+9*x[3]**2+((-2*x[2])-2*x[1]-2*x[0])*x[3]+9*x[2]**2+((-2*x[1])-2*x[0])*x[2]+9*x[1]**2-2*x[0]*x[1]+9*x[0]**2)
b = -(((x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0])*x[9]-x[8]**2-x[7]**2-x[6]**2-x[5]**2-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[9]+((-y[8])-y[7]-y[6]-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[9]**2+(x[8]*y[8]+x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[9]+((x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0])*x[8]-x[7]**2-x[6]**2-x[5]**2-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[8]+((-y[7])-y[6]-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[8]**2+(x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[8]+((x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0])*x[7]-x[6]**2-x[5]**2-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[7]+((-y[6])-y[5]-y[4]-y[3]-y[2]-y[1]-y[0])*x[7]**2+(x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[7]+((x[5]+x[4]+x[3]+x[2]+x[1]+x[0])*x[6]-x[5]**2-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[6]+((-y[5])-y[4]-y[3]-y[2]-y[1]-y[0])*x[6]**2+(x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[6]+((x[4]+x[3]+x[2]+x[1]+x[0])*x[5]-x[4]**2-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[5]+((-y[4])-y[3]-y[2]-y[1]-y[0])*x[5]**2+(x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[5]+((x[3]+x[2]+x[1]+x[0])*x[4]-x[3]**2-x[2]**2-x[1]**2-x[0]**2)*y[4]+((-y[3])-y[2]-y[1]-y[0])*x[4]**2+(x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[4]+((x[2]+x[1]+x[0])*x[3]-x[2]**2-x[1]**2-x[0]**2)*y[3]+((-y[2])-y[1]-y[0])*x[3]**2+(x[2]*y[2]+x[1]*y[1]+x[0]*y[0])*x[3]+((x[1]+x[0])*x[2]-x[1]**2-x[0]**2)*y[2]+((-y[1])-y[0])*x[2]**2+(x[1]*y[1]+x[0]*y[0])*x[2]+(x[0]*x[1]-x[0]**2)*y[1]-y[0]*x[1]**2+x[0]*y[0]*x[1])/(9*x[9]**2+((-2*x[8])-2*x[7]-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[9]+9*x[8]**2+((-2*x[7])-2*x[6]-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[8]+9*x[7]**2+((-2*x[6])-2*x[5]-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[7]+9*x[6]**2+((-2*x[5])-2*x[4]-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[6]+9*x[5]**2+((-2*x[4])-2*x[3]-2*x[2]-2*x[1]-2*x[0])*x[5]+9*x[4]**2+((-2*x[3])-2*x[2]-2*x[1]-2*x[0])*x[4]+9*x[3]**2+((-2*x[2])-2*x[1]-2*x[0])*x[3]+9*x[2]**2+((-2*x[1])-2*x[0])*x[2]+9*x[1]**2-2*x[0]*x[1]+9*x[0]**2)

plt.clf(); plt.grid()
plt.scatter(x, y, marker='.', label='test data', alpha=0.9)
plt.plot([], []) # adhoc
X = [min(x), max(x)]
plt.plot(X, [a*X[0] + b, a*X[-1] + b], label='$ y = a x + b $', alpha=0.9)
plt.legend(loc='best')
plt.title('$ a = {},\\ b = {} $'.format(a, b))
plt.xlabel('$ x $'); plt.ylabel('$ y $')
plt.savefig('fig1.svg')

(最小二乗法の、M 次式のより)ベクトルと行列で表現\[ \begin{align} A\mathbf w &= \mathbf{b} \\ \begin{pmatrix} \sum\limits_i^{N-1} x_i^{0 + 0} & \sum\limits_i^{N-1} x_i^{0 + 1} \\ \sum\limits_i^{N-1} x_i^{1 + 0} & \sum\limits_i^{N-1} x_i^{1 + 1} \end{pmatrix}\begin{pmatrix} w_0 \\ w_1 \end{pmatrix} &= \begin{pmatrix} \sum\limits_i^{N-1} x_i^0 y_i \\ \sum\limits_i^{N-1} x_i^1 y_i \end{pmatrix} \\ \begin{pmatrix} \sum\limits_i^{N-1} 1 & \sum\limits_i^{N-1} x_i \\ \sum\limits_i^{N-1} x_i & \sum\limits_i^{N-1} x_i^2 \end{pmatrix}\begin{pmatrix} w_0 \\ w_1 \end{pmatrix} &= \begin{pmatrix} \sum\limits_i^{N-1} y_i \\ \sum\limits_i^{N-1} x_i y_i \end{pmatrix} \\ \mathbf w &= A^{-1} \mathbf{b} \\ \begin{pmatrix} b \\ a \end{pmatrix} = \begin{pmatrix} w_0 \\ w_1 \end{pmatrix} &= \begin{pmatrix} \sum\limits_i^{N-1} 1 & \sum\limits_i^{N-1} x_i \\ \sum\limits_i^{N-1} x_i & \sum\limits_i^{N-1} x_i^2 \end{pmatrix}^{-1}\begin{pmatrix} \sum\limits_i^{N-1} y_i \\ \sum\limits_i^{N-1} x_i y_i \end{pmatrix} \end{align} \]

(Maxima による、記号計算)

Maxima
(%i1) invert(matrix([sum(1, i, 0, 9), sum(x[i], i, 0, 9)], [sum(x[i], i, 0, 9), sum(x[i]^2, i, 0, 9)])).matrix([sum(y[i], i, 0, 9)], [sum(x[i]*y[i], i, 0, 9)]);
(%o1) matrix([(((- x ) - x  - x  - x  - x  - x  - x  - x  - x  - x )
                    9     8    7    6    5    4    3    2    1    0
 (x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y
   9  9    8  8    7  7    6  6    5  5    4  4    3  3    2  2    1  1
                 2    2    2    2    2    2    2    2    2    2
 + x  y ))/(10 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x )
    0  0         9    8    7    6    5    4    3    2    1    0
 + ((- x ) - x  - x  - x  - x  - x  - x  - x  - x  - x )
        9     8    7    6    5    4    3    2    1    0
 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x ))
   9    8    7    6    5    4    3    2    1    0
      2    2    2    2    2    2    2    2    2    2
 + ((x  + x  + x  + x  + x  + x  + x  + x  + x  + x )
      9    8    7    6    5    4    3    2    1    0
 (y  + y  + y  + y  + y  + y  + y  + y  + y  + y ))
   9    8    7    6    5    4    3    2    1    0
       2    2    2    2    2    2    2    2    2    2
/(10 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x )
       9    8    7    6    5    4    3    2    1    0
 + ((- x ) - x  - x  - x  - x  - x  - x  - x  - x  - x )
        9     8    7    6    5    4    3    2    1    0
 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x ))], 
   9    8    7    6    5    4    3    2    1    0
[(10 (x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y  + x  y
       9  9    8  8    7  7    6  6    5  5    4  4    3  3    2  2    1  1
                 2    2    2    2    2    2    2    2    2    2
 + x  y ))/(10 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x )
    0  0         9    8    7    6    5    4    3    2    1    0
 + ((- x ) - x  - x  - x  - x  - x  - x  - x  - x  - x )
        9     8    7    6    5    4    3    2    1    0
 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x ))
   9    8    7    6    5    4    3    2    1    0
 + (((- x ) - x  - x  - x  - x  - x  - x  - x  - x  - x )
         9     8    7    6    5    4    3    2    1    0
 (y  + y  + y  + y  + y  + y  + y  + y  + y  + y ))
   9    8    7    6    5    4    3    2    1    0
       2    2    2    2    2    2    2    2    2    2
/(10 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x )
       9    8    7    6    5    4    3    2    1    0
 + ((- x ) - x  - x  - x  - x  - x  - x  - x  - x  - x )
        9     8    7    6    5    4    3    2    1    0
 (x  + x  + x  + x  + x  + x  + x  + x  + x  + x ))])
   9    8    7    6    5    4    3    2    1    0

(%i2) fortran(b = %th(1)[1][1]); /* w0 */
      b = (((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]*
     1   y[9]+x[8]*y[8]+x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3
     2   ]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0]))/(10*(x[9]**2+x[8]**2+x[7]**2+
     3   x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)+((-x[9
     4   ])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]+x[8]+x[7
     5   ]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))+((x[9]**2+x[8]**2+x[7]**
     6   2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)*(y[9
     7   ]+y[8]+y[7]+y[6]+y[5]+y[4]+y[3]+y[2]+y[1]+y[0]))/(10*(x[9]**2+x
     8   [8]**2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+
     9   x[0]**2)+((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])
     :   *(x[9]+x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))
(%o2)                                done
(%i3) fortran(a = %th(2)[2][1]); /* w1 */
      a = (10*(x[9]*y[9]+x[8]*y[8]+x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[
     1   4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0]))/(10*(x[9]**2+x[8]*
     2   *2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]
     3   **2)+((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[
     4   9]+x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))+(((-x[9])-x[8
     5   ]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(y[9]+y[8]+y[7]+y[6]
     6   +y[5]+y[4]+y[3]+y[2]+y[1]+y[0]))/(10*(x[9]**2+x[8]**2+x[7]**2+x
     7   [6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)+((-x[9]
     8   )-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]+x[8]+x[7]
     9   +x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))
(%o3)                                done

(同じテストデータを使用して、)解を表示して確認

Python
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

# test data
x = [0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306]
y = [-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183]

# solution
b = (((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]*y[9]+x[8]*y[8]+x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0]))/(10*(x[9]**2+x[8]**2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)+((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]+x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))+((x[9]**2+x[8]**2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)*(y[9]+y[8]+y[7]+y[6]+y[5]+y[4]+y[3]+y[2]+y[1]+y[0]))/(10*(x[9]**2+x[8]**2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)+((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]+x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))
a = (10*(x[9]*y[9]+x[8]*y[8]+x[7]*y[7]+x[6]*y[6]+x[5]*y[5]+x[4]*y[4]+x[3]*y[3]+x[2]*y[2]+x[1]*y[1]+x[0]*y[0]))/(10*(x[9]**2+x[8]**2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)+((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]+x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))+(((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(y[9]+y[8]+y[7]+y[6]+y[5]+y[4]+y[3]+y[2]+y[1]+y[0]))/(10*(x[9]**2+x[8]**2+x[7]**2+x[6]**2+x[5]**2+x[4]**2+x[3]**2+x[2]**2+x[1]**2+x[0]**2)+((-x[9])-x[8]-x[7]-x[6]-x[5]-x[4]-x[3]-x[2]-x[1]-x[0])*(x[9]+x[8]+x[7]+x[6]+x[5]+x[4]+x[3]+x[2]+x[1]+x[0]))

plt.clf(); plt.grid()
plt.scatter(x, y, marker='.', label='test data', alpha=0.9)
plt.plot([], []) # adhoc
X = [min(x), max(x)]
plt.plot(X, [a*X[0] + b, a*X[-1] + b], label='$ y = a x + b $', alpha=0.9)
plt.legend(loc='best')
plt.title('$ a = {},\\ b = {} $'.format(a, b))
plt.xlabel('$ x $'); plt.ylabel('$ y $')
plt.savefig('fig2.svg')

\( \Sigma \) が展開されないようにして、解を求める

Maxima
(%i1) invert(matrix(['sum(1, i, 0, 9), 'sum(x[i], i, 0, 9)], ['sum(x[i], i, 0, 9), 'sum(x[i]^2, i, 0, 9)])).matrix(['sum(y[i], i, 0, 9)], ['sum(x[i]*y[i], i, 0, 9)]);
           [      9         9               9         9            ]
           [     ====      ====            ====      ====          ]
           [     \      2  \               \         \             ]
           [    ( >    x )  >    y        ( >    x )  >    x  y    ]
           [     /      i  /      i        /      i  /      i  i   ]
           [     ====      ====            ====      ====          ]
           [     i = 0     i = 0           i = 0     i = 0         ]
           [ ------------------------- - ------------------------- ]
           [     9           9               9           9         ]
           [    ====        ====            ====        ====       ]
           [    \      2    \        2      \      2    \        2 ]
           [ 10  >    x  - ( >    x )    10  >    x  - ( >    x )  ]
           [    /      i    /      i        /      i    /      i   ]
           [    ====        ====            ====        ====       ]
           [    i = 0       i = 0           i = 0       i = 0      ]
(%o1)      [                                                       ]
           [          9                       9         9          ]
           [         ====                    ====      ====        ]
           [         \                       \         \           ]
           [      10  >    x  y             ( >    x )  >    y     ]
           [         /      i  i             /      i  /      i    ]
           [         ====                    ====      ====        ]
           [         i = 0                   i = 0     i = 0       ]
           [ ------------------------- - ------------------------- ]
           [     9           9               9           9         ]
           [    ====        ====            ====        ====       ]
           [    \      2    \        2      \      2    \        2 ]
           [ 10  >    x  - ( >    x )    10  >    x  - ( >    x )  ]
           [    /      i    /      i        /      i    /      i   ]
           [    ====        ====            ====        ====       ]
           [    i = 0       i = 0           i = 0       i = 0      ]
(%i2) tex(matrix([b], [a]) = %th(1));
\[ \begin{pmatrix} b\cr a \cr \end{pmatrix} = \begin{pmatrix} {{\left( \sum_{i=0}^{9}{x_{i}^2}\right)\,\sum_{i=0}^{9}{y_{i}}}\over{10\, \sum_{i=0}^{9}{x_{i}^2}-\left(\sum_{i=0}^{9}{x_{i}}\right)^2}}-{{ \left(\sum_{i=0}^{9}{x_{i}}\right)\,\sum_{i=0}^{9}{x_{i}\,y_{i}} }\over{10\,\sum_{i=0}^{9}{x_{i}^2}-\left(\sum_{i=0}^{9}{x_{i}} \right)^2}}\cr {{10\,\sum_{i=0}^{9}{x_{i}\,y_{i}}}\over{10\,\sum_{i= 0}^{9}{x_{i}^2}-\left(\sum_{i=0}^{9}{x_{i}}\right)^2}}-{{\left( \sum_{i=0}^{9}{x_{i}}\right)\,\sum_{i=0}^{9}{y_{i}}}\over{10\,\sum_{ i=0}^{9}{x_{i}^2}-\left(\sum_{i=0}^{9}{x_{i}}\right)^2}}\cr \end{pmatrix} \]

(%o2)                                false
(%i3) tex(matrix([b], [a]) = ratsimp(%th(2)));
\[ \begin{pmatrix} b\cr a \cr \end{pmatrix} = \begin{pmatrix} -{{\left( \sum_{i=0}^{9}{x_{i}}\right)\,\sum_{i=0}^{9}{x_{i}\,y_{i}}-\left( \sum_{i=0}^{9}{x_{i}^2}\right)\,\sum_{i=0}^{9}{y_{i}}}\over{10\, \sum_{i=0}^{9}{x_{i}^2}-\left(\sum_{i=0}^{9}{x_{i}}\right)^2}}\cr {{ 10\,\sum_{i=0}^{9}{x_{i}\,y_{i}}-\left(\sum_{i=0}^{9}{x_{i}}\right) \,\sum_{i=0}^{9}{y_{i}}}\over{10\,\sum_{i=0}^{9}{x_{i}^2}-\left( \sum_{i=0}^{9}{x_{i}}\right)^2}}\cr \end{pmatrix} \]

(%o3)                                false

(%i4) fortran(b = ratsimp(%th(3)[1][1]));
      b = -(('sum(x[i],i,0,9))*'sum(x[i]*y[i],i,0,9)-('sum(x[i]**2,i,0,9
     1   ))*'sum(y[i],i,0,9))/(10*'sum(x[i]**2,i,0,9)-('sum(x[i],i,0,9))
     2   **2)
(%o4)                                done
(%i5) fortran(a = ratsimp(%th(4)[2][1]));
      a = (10*'sum(x[i]*y[i],i,0,9)-('sum(x[i],i,0,9))*'sum(y[i],i,0,9))
     1   /(10*'sum(x[i]**2,i,0,9)-('sum(x[i],i,0,9))**2)
(%o5)                                done

(Maxima では、シングルクォート演算子「'」は、シンボルの評価を抑制する)

(同じテストデータを使用して、)検算

IPython
$ ipython3
Python 3.12.3 (main, Sep 11 2024, 14:17:37) [GCC 13.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.20.0 -- An enhanced Interactive Python. Type '?' for help.


In [1]: x = [0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306]

In [2]: y = [-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183]

In [3]: b = -((sum([x for x in x]))*sum([x*y for x, y in zip(x, y)])-(sum([x**2 for x in x]))*sum([y for y in y]))/(10*sum([x**2 for x in x])-(sum([x for x in x]))**2); b
Out[3]: -0.31682418530985723

In [4]: a = (10*sum([x*y for x, y in zip(x, y)])-(sum([x for x in x]))*sum([y for y in y]))/(10*sum([x**2 for x in x])-(sum([x for x in x]))**2); a
Out[4]: 0.4719094236134641

解が等しいことを確認(求めた係数 \( a = 0.4719094236134641,\ b = -0.31682418530985723 \))

(Python のリスト内包表記と zip() 関数を利用して、sum() を計算)

行列計算により求める

(Octave、R 言語を使用)

OctaveR 言語
x = [0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306]
y = [-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183]

A = [sum(ones(size(x))) sum(x); sum(x) sum(x.^2)]
b = [sum(y); sum(x.*y)]

w = A\b
x <- c(0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306)
y <- c(-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183)

A <- matrix(c(sum(rep(1, length(x))), sum(x), sum(x), sum(x^2)), ncol=2, byrow=TRUE)
b <- c(sum(y), sum(x*y))

w <- solve(A, b)

上記の式を、式のとおりに解く\[ \begin{align} A\mathbf w &= \mathbf{b} \\ \begin{pmatrix} \sum\limits_i^{N-1} 1 & \sum\limits_i^{N-1} x_i \\ \sum\limits_i^{N-1} x_i & \sum\limits_i^{N-1} x_i^2 \end{pmatrix}\begin{pmatrix} w_0 \\ w_1 \end{pmatrix} &= \begin{pmatrix} \sum\limits_i^{N-1} y_i \\ \sum\limits_i^{N-1} x_i y_i \end{pmatrix} \\ \begin{pmatrix} w_0 \\ w_1 \end{pmatrix} &= \begin{pmatrix} \sum\limits_i^{N-1} 1 & \sum\limits_i^{N-1} x_i \\ \sum\limits_i^{N-1} x_i & \sum\limits_i^{N-1} x_i^2 \end{pmatrix}^{-1}\begin{pmatrix} \sum\limits_i^{N-1} y_i \\ \sum\limits_i^{N-1} x_i y_i \end{pmatrix} \\ \mathbf w &= A^{-1} \mathbf{b} \end{align} \]

スクリプトの実行結果

Octave
$ octave --no-gui
GNU Octave, version 8.4.0
Copyright (C) 1993-2023 The Octave Project Developers.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "x86_64-pc-linux-gnu".

Additional information about Octave is available at https://www.octave.org.

Please contribute if you find this software useful.
For more information, visit https://www.octave.org/get-involved.html

Read https://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.


octave:1> x = [0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306]
x =

   0.6989  -0.7830   0.3114  -0.3149   0.7490   0.9409  -0.4365   0.1195  -0.2201   0.9987

octave:2> y = [-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183]
y =

 Columns 1 through 8:

  -0.137733  -0.607964   0.057463  -0.460887  -0.063810   0.240212  -0.589843  -0.206655

 Columns 9 and 10:

  -0.575967   0.150842

octave:3> format long
octave:4> A = [sum(ones(size(x))) sum(x); sum(x) sum(x.^2)]
A =

   1.000000000000000e+01   2.063744300000000e+00
   2.063744300000000e+00   3.994641996397790e+00

octave:5> b = [sum(y); sum(x.*y)]
b =

  -2.194341470000000
   1.231265095526857

octave:6> w = A\b
w =

  -0.316824185309857
   0.471909423613464

R
$ R

R version 4.3.3 (2024-02-29) -- "Angel Food Cake"
Copyright (C) 2024 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R は、自由なソフトウェアであり、「完全に無保証」です。 
一定の条件に従えば、自由にこれを再配布することができます。 
配布条件の詳細に関しては、'license()' あるいは 'licence()' と入力してください。 

R は多くの貢献者による共同プロジェクトです。 
詳しくは 'contributors()' と入力してください。 
また、R や R のパッケージを出版物で引用する際の形式については 
'citation()' と入力してください。 

'demo()' と入力すればデモをみることができます。 
'help()' とすればオンラインヘルプが出ます。 
'help.start()' で HTML ブラウザによるヘルプがみられます。 
'q()' と入力すれば R を終了します。 


> x <- c(0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306)
> y <- c(-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183)
> (A <- matrix(c(sum(rep(1, length(x))), sum(x), sum(x), sum(x^2)), ncol=2, byrow=TRUE))
          [,1]     [,2]
[1,] 10.000000 2.063744
[2,]  2.063744 3.994642
> (b <- c(sum(y), sum(x*y)))
[1] -2.194341  1.231265
> (w <- solve(A, b))
[1] -0.3168242  0.4719094

(同じテストデータを使用して、)同じ係数が求まっている


C/C++ 言語による実装

Maxima を使用して、記号計算で解く(連立方程式の形で解いているが、逆行列を求めていることと同じ)

Maxima
% maxima
Maxima 5.47.0 https://maxima.sourceforge.io
using Lisp SBCL 2.4.11
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.

(%i1) matrix([a[0,0], a[0,1]], [a[1,0], a[1,1]]).matrix([w[0]], [w[1]]) = matrix([b[0]], [b[1]]);
                       [ a     w  + w  a     ]   [ b  ]
                       [  0, 1  1    0  0, 0 ]   [  0 ]
(%o1)                  [                     ] = [    ]
                       [ w  a     + w  a     ]   [ b  ]
                       [  1  1, 1    0  1, 0 ]   [  1 ]
(%i2) solve([lhs(%th(1))[1,1] = rhs(%th(1))[1,1], lhs(%th(1))[2,1] = rhs(%th(1))[2,1]], [w[0], w[1]]);
                a     b  - b  a                   a     b  - b  a
                 0, 1  1    0  1, 1                0, 0  1    0  1, 0
(%o2) [[w  = -------------------------, w  = - -------------------------]]
         0   a     a     - a     a       1     a     a     - a     a
              0, 1  1, 0    0, 0  1, 1          0, 1  1, 0    0, 0  1, 1

(%i3) fortran(%th(1)[1][1]);
      w[0] = (a[0,1]*b[1]-b[0]*a[1,1])/(a[0,1]*a[1,0]-a[0,0]*a[1,1])
(%o3)                                done
(%i4) fortran(%th(2)[1][2]);
      w[1] = -((a[0,0]*b[1]-b[0]*a[1,0])/(a[0,1]*a[1,0]-a[0,0]*a[1,1]))
(%o4)                                done

(Maxima で「.」演算子は非可換の乗算、行列の積)

Maxima の fortran() 関数で FORTRAN の式として書き出したものを、C 言語の式に直して(エディタの置換コマンドで「,」を「][」に変換しただけ)、そのまま C/C++ 言語で実装

C/C++ 言語
#define M 2

#include <assert.h>

static void solve_w(const double a[M][M], double w[M], const double b[M]) {
	assert(M == 2);
	w[0] = (a[0][1]*b[1]-b[0]*a[1][1])/(a[0][1]*a[1][0]-a[0][0]*a[1][1]);
	w[1] = -((a[0][0]*b[1]-b[0]*a[1][0])/(a[0][1]*a[1][0]-a[0][0]*a[1][1]));
}

#include <stdio.h>
#include <string.h>
#include <math.h>

int main(int argc, char *argv[])
{
	const double x[] = {0.6988692, -0.7830310, 0.3113822, -0.3149006, 0.7489550, 0.9408923, -0.4365415, 0.1194887, -0.2201006, 0.9987306};
	const double y[] = {-0.13773286, -0.60796351, 0.05746277, -0.46088667, -0.06380987, 0.24021167, -0.58984292, -0.20665464, -0.57596727, 0.15084183};
	const int n = sizeof(x)/sizeof(x[0]);
	assert(sizeof(x) == sizeof(y));
	double a[M][M];
	memset(a, 0x00, sizeof(a));
	assert(M == 2);
	a[0][0] = 1*n;
	for (int i = 0; i < n; i++) a[0][1] += x[i];
	a[1][0] = a[0][1];
	for (int i = 0; i < n; i++) a[1][1] += pow(x[i], 2);
	double b[M];
	memset(b, 0x00, sizeof(b));
	assert(M == 2);
	for (int i = 0; i < n; i++) b[0] += y[i];
	for (int i = 0; i < n; i++) b[1] += x[i]*y[i];
	double w[M];
	memset(w, 0x00, sizeof(w));
	solve_w(a, w, b);
	assert(M == 2);
	printf("%f %f\n", w[0], w[1]);
}

#undef M

% clang -Wall solve_w.cpp && ./a.out
-0.316824 0.471909

(同じ係数を計算できている)

... ToDo ...
... ToDo ...
... ToDo ...

掃き出し法、ピボット選択

... ToDo ...
... ToDo ...
... ToDo ...


正規方程式(normal equations)

(天下り)\[ \mathbf t = \Phi \mathbf w \]ここで、\( \mathbf t = \begin{pmatrix} y_0 \\ y_1 \\ \vdots \\ y_{n-1} \end{pmatrix} \)、\( \Phi \) は計画行列(design matrix)

... W.I.P. ...
... W.I.P. ...
... W.I.P. ...

... W.I.P. ...
... W.I.P. ...
... W.I.P. ...

... W.I.P. ...
... W.I.P. ...
... W.I.P. ...


© 2024 Tadakazu Nagai