전산물리학:선형_회귀_분석_linear_regression_analysis

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revisionBoth sides next revision
전산물리학:선형_회귀_분석_linear_regression_analysis [2022/01/16 12:11] jonghoon전산물리학:선형_회귀_분석_linear_regression_analysis [2022/01/17 16:12] jonghoon
Line 9: Line 9:
 $$ \chi^2 = \sum_{i=1}^{N}\left(\frac{y_i - f(x_i)}{\sigma_i}\right)^2$$ $$ \chi^2 = \sum_{i=1}^{N}\left(\frac{y_i - f(x_i)}{\sigma_i}\right)^2$$
  
-Python의 경우 scipy의 curve_fitting 함수를 사용할 수 있고, C/C++의 경우 gsl(gnu scientific library)의 gsl_fit_linear 혹은 gsl_fit_wlinear를 사용할 수 있다. 데이터에 표준오차가 포함되어 있는 경우에는 wlinear를 포함되지 않은 경우에는 linear를 사용한다. scipy를 쓸 때는 표준오차가 포함되어 있는 경우에는 absolute_sigma 옵션을 True로 줘야 한다.+Python의 경우 scipy의 curve_fitting 함수를 사용할 수 있고, C/C++의 경우 gsl(gnu scientific library)의 gsl_fit_linear 혹은 gsl_fit_wlinear를 사용할 수 있다. 데이터에 표준오차가 포함되어 있는 경우에는 wlinear를포함되지 않은 경우에는 linear를 사용한다. wlinear를 쓸 때는 표준오차 값의 제곱의 역수를 w값으로 넣줘야 한다. gsl의 경우 
 +$$\chi^2 = w(y-f(x))^2;\quad w = \frac{1}{\sigma^2}$$ 
 +로 계산하기 때문이다.
  
 +scipy를 쓸 때는 표준오차가 포함되어 있는 경우에는 absolute_sigma 옵션을 True로 줘야 한다.
 +====== 실습 =======
 다음의 데이터를 예로 각 언어로 적합(fitting)해보자. 다음의 데이터를 예로 각 언어로 적합(fitting)해보자.
  
Line 35: Line 39:
 | 4.75 | 10.519384785632700 | 0.47616567472190800 | | 4.75 | 10.519384785632700 | 0.47616567472190800 |
  
 +===== Python =====
 먼저 Python 코드는 아래와 같다. 먼저 Python 코드는 아래와 같다.
-<Code:Python+ 
-from scipy.optimize import curve_fit+<code:Python curve_fit.py>
 import numpy as np import numpy as np
 +from scipy.optimize import curve_fit
  
 func = lambda x, a, b: a*x + b #f(x) = ax + b func = lambda x, a, b: a*x + b #f(x) = ax + b
  
-x = np.linspace(0, 4.75, 16) #x = [0.00, 0.25, 0.50, \ldots]+x = np.linspace(0, 4.75, 20) #x = [0.00, 0.25, 0.50, ...]
  
 y = np.array([1.5891700001638700, 1.2046979031630900, 2.598484110379440, 2.2043375760987900, 3.002229375836470, 2.928655222350250, 3.4769844321649000, 4.007335261529810, 4.534192485682100, 5.76185759925369, 6.41954394976063, 6.023919923933230, 7.443742735575060, 7.870686775946450, 8.022587710435350, 9.395420889477870, 9.948288024421440, 9.986332770533490, 9.694674681091840, 10.519384785632700]) y = np.array([1.5891700001638700, 1.2046979031630900, 2.598484110379440, 2.2043375760987900, 3.002229375836470, 2.928655222350250, 3.4769844321649000, 4.007335261529810, 4.534192485682100, 5.76185759925369, 6.41954394976063, 6.023919923933230, 7.443742735575060, 7.870686775946450, 8.022587710435350, 9.395420889477870, 9.948288024421440, 9.986332770533490, 9.694674681091840, 10.519384785632700])
Line 56: Line 62:
 popt, pcov = curve_fit(func, x, y, sigma = sig, absolute_sigma = True) #popt: inferenced coefficient, pcov: covariance between coefficients popt, pcov = curve_fit(func, x, y, sigma = sig, absolute_sigma = True) #popt: inferenced coefficient, pcov: covariance between coefficients
 perr = np.sqrt(np.diag(pcov))# diagonal elements of covariance matrix are error of each coefficient perr = np.sqrt(np.diag(pcov))# diagonal elements of covariance matrix are error of each coefficient
-chi2 = np.sum((y-func+chi2 = np.sum((y - func(x,*popt))**2 / sig**2) 
 + 
 +print("y = {0}x + {1}".format(popt[0],popt[1]) 
 +</code> 
 + 
 +===== C++ ===== 
 +다음은 C++에서 gsl을 이용한 코드이다. 
 +<code:C++ | curve_fit.cpp> 
 +#include <iostream> 
 +#include <gsl/gsl_fit.h> 
 +#include <cmath> 
 + 
 +using std::cout; 
 +using std::pow; 
 +using std::sqrt; 
 + 
 +// #include <fstream> 
 +// #include <sstream> 
 +// #include <string> 
 +// #include <vector> 
 + 
 +//using std::ifstream; 
 +//using std::istringstream; 
 +//using std::vector; 
 +//using std::string; 
 +//using std::stod; 
 +//using std::copy; 
 + 
 +int main() 
 +
 +    double x[] = {0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5, 4.75}; 
 +    double y[] = {1.5891700001638700, 1.2046979031630900, 2.598484110379440, 2.2043375760987900, 3.002229375836470, 2.928655222350250, 3.4769844321649000, 4.007335261529810, 4.534192485682100, 5.76185759925369, 6.41954394976063, 6.023919923933230, 7.443742735575060, 7.870686775946450, 8.022587710435350, 9.395420889477870, 9.948288024421440, 9.986332770533490, 9.694674681091840, 10.519384785632700}; 
 +    double sig[] = {0.5320185951347170, 0.45427229254919400, 0.5077027054798450, 0.5205826529502230, 0.4698090780151540, 0.4773624121076510, 0.5018787752525470, 0.4897362325985810, 0.49462141854510300, 0.5405394898833090, 0.4523449367708450, 0.48898047501417500, 0.5342659697011440, 0.4730380798563350, 0.4572104512757930, 0.49902577926821200, 0.530527413902035, 0.48969676619036700, 0.5443240285483060, 0.47616567472190800}; 
 +     
 +    //if saved file is existed 
 +    /* 
 +    string tmp; 
 +    std::ifstream fin; 
 +    fin.open("line.dat"); 
 +     
 +    vector<double> xv; 
 +    vector<double> yv; 
 +    vector<double> sigv; 
 +    vector<string> sv; 
 +    string sbf; 
 +     
 +    while(!fin.eof()) 
 +    { 
 +        getline(fin, tmp); 
 +        if(tmp == "") {break;} 
 +        istringstream ss(tmp); 
 +        while(getline(ss,sbf,',')) 
 +        { 
 +            sv.emplace_bacK(); 
 +        } 
 +        sv.shrink_to_fit(); 
 +         
 +        xv.emplace_back(stod(sv[0])); 
 +        yv.emplace_back(stod(sv[1])); 
 +        sigv.emplace_back(stod(sv[2])); 
 +         
 +        sv.clear(); 
 +        sv.shrink_to_fit(); 
 +    } 
 +    xv.shrink_to_fit(); 
 +    yv.shrink_to_fit(); 
 +    sigv.shrink_to_fit(); 
 +     
 +    double x[xv.capacity()]; 
 +    double y[yv.capacity()]; 
 +    double sig[sig.capacity()]; 
 +     
 +    copy(xv.begin(), xv.end(), x); 
 +    copy(yv.begin(), yv.end(), y); 
 +    copy(sigv.begin(), sigv.end(), sig); 
 +    */ 
 + 
 +    for(int i = 0; i < sizeof(sig)/sizeof(double); ++i) 
 +    { 
 +        sig[i] = 1/sig[i]; 
 +    } 
 + 
 +    double a, b, cov00, cov01, cov11, chisq; 
 +    gsl_fit_wlinear(x, 1, sig, 1, y, 1, sizeof(x)/sizeof(double), &b, &a, &cov00, &cov01, &cov11, &chisq); 
 +    cout << "y = " << a << "x + "<< b << "\n"; 
 +
 +</code>
  
-</Code>+===== 결과 ===== 
 +각각의 결과는 다음과 같다 
 +$$\text{Python:}\quad y = 2.09749(\pm 0.0771828)x + 0.838641(\pm 0.213449)$$ 
 +$$\text{C++:}\quad y = 2.09749(\pm 0.0771828)x + 0.838641(\pm 0.0.213449)$$ 
 +유효숫자는 c++ cout의 기본 자릿수인 6자리에 맞췄다.
  • 전산물리학/선형_회귀_분석_linear_regression_analysis.txt
  • Last modified: 2023/09/05 15:46
  • by 127.0.0.1