まえがき
今回試してみたのは、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);
}
//----------------------------------------------------------------------------