전산물리학:선형_회귀_분석_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
전산물리학:선형_회귀_분석_linear_regression_analysis [2022/01/16 12:11] jonghoon전산물리학:선형_회귀_분석_linear_regression_analysis [2023/09/05 15:46] (current) – external edit 127.0.0.1
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.1642302706.txt.gz
  • Last modified: 2023/09/05 15:46
  • (external edit)