まえがき
今回試してみたのは、Y=C0+Cn×X^Cnの多項式回帰です。n値を変えることで以下の様に変化します。
n=2の時
n=3の時
n=4の時
n=10の時
サンプル
サンプルコードは、ここです。※上記n値は、変数名Pwです。
DLLコード
※前回のコードをそのまま残し、修正しました。#pragma once #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <stdlib.h> #include <stdio.h> #include <math.h>//数学用 #include ".\include\gsl\gsl_sort.h"//配列並び替え用 #include ".\include\gsl\gsl_wavelet.h"//ウェーブレット用 #include ".\include\gsl\gsl_multifit.h"//重回帰 BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { //---- switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } //---- return(TRUE); } //+-------------------------------------------------------------------+ //|重回帰(Multifit_liner)Y=c0+c1X+c2X^2+c3X^3...cpwX^pw //|input[] 入力用バッファ //|pw 変数量 //|out[pw+1] 出力用バッファ[c0,c1,c2,c3,....cpw.chisq] //|Ns 対象データ数 //+-------------------------------------------------------------------+ __declspec(dllexport) void __stdcall Multifit_liner(double *input,int pw,double *out,int Ns){ int i,ipw; double ix,chisq; gsl_matrix *X, *cov; gsl_vector *y, *w, *c; //配列(ベクトル配列)の確保 X = gsl_matrix_alloc(Ns, pw); y = gsl_vector_alloc(Ns); c = gsl_vector_alloc(pw); cov = gsl_matrix_alloc(pw, pw); //配列(ベクトル配列)入力 for(i=0;i<Ns;i++){ ix = i*0.001; gsl_matrix_set (X, i, 0, 1.0); for(ipw=1;ipw<pw;ipw++)gsl_matrix_set (X, i, ipw, pow(ix,ipw)); gsl_vector_set (y, i, input[i]); } //処理 gsl_multifit_linear_workspace *work = gsl_multifit_linear_alloc (Ns, pw); gsl_multifit_linear(X,y,c,cov,&chisq,work); gsl_multifit_linear_free (work); //抽出 for(i=0;i<pw;i++)out[i]=gsl_vector_get(c,(i)); out[pw]=chisq; //メモリ解放 gsl_matrix_free(X); gsl_matrix_free(cov); gsl_vector_free(y); gsl_vector_free(c); } //+-------------------------------------------------------------------+ //|ウェーブレット変換(DWT) //|input[] 入力用バッファ //|out[] 出力用バッファ //|Ns 対象データ数(2のNs乗) //|D ウェーブレット係数(2:Harr 4~daubechies //|fs フィルタ //+-------------------------------------------------------------------+ __declspec(dllexport) void __stdcall DWT(double *input,double *out,int Ns,int D,int fs){ int i; int siz = (int)pow(2.0,Ns); if(D%2==1)D++; if(D>20)D=20; //配列のコピー memcpy(out,input,sizeof(double)*siz); //ウェーブレットの初期設定(ウェーブレット名,D値) gsl_wavelet *w; if(D==2){ w = gsl_wavelet_alloc(gsl_wavelet_haar,D); }else{ w = gsl_wavelet_alloc(gsl_wavelet_daubechies, D); } //作業領域の確保(数量) gsl_wavelet_workspace *work; work = gsl_wavelet_workspace_alloc(siz); size_t *p = (size_t *)malloc(siz * sizeof(size_t)); double *abs = (double *)malloc(siz * sizeof (double)); if (abs == NULL || p== NULL){printf("メモリを確保できません"); exit(0);} //変換(初期設定,データ,進み幅,作業エリア) gsl_wavelet_transform_forward(w, out, 1, siz,work); //フィルタ作業 for(i = 0; i < siz; i++) abs[i] = fabs(out[i]); gsl_sort_index(p, abs, 1, siz); for(i = 0; (i + fs) < siz; i++) out[p[i]] = 0; //逆変換 gsl_wavelet_transform_inverse(w, out, 1, siz, work); //メモリ解放 free(abs); free(p); gsl_wavelet_workspace_free(work); gsl_wavelet_free(w); } //----------------------------------------------------------------------------