曲線がC1クラスかC2クラスかを確認する方法。
例:
x = [1,2,3,4,5,6,7,8,9 ......1500]
y = [0.56, 1, 12, 41, 01. ....... 11, 0.11, 3, 23, 95]
この曲線はC1クラスの「関数」ですか?
どうもありがとうございます。
MatLabベクトルには、関数自体ではなく、関数のサンプルが含まれています。
サンプリングされたデータは常に離散的であり、連続的ではありません。
同じサンプルを持つ関数は無限にあります。具体的には、これらのサンプルには常に連続関数と不連続関数の両方があるため、サンプルだけからC1かどうかを判断する方法はありません。
連続関数の例:フーリエ(またはDCT)で再構成された推定。
不連続関数の例:フーリエ再構成された推定値に加えて、サンプリングレートに等しい周期ののこぎり波。
与えられたデータからはわかりません。それから関数をどのように表現するかについて何かを知る必要があります。
たとえば、それらをヒストグラムとしてプロットすると、不連続になります(各ポイントでジャンプします)。ポイント間で直線補間を行うと、C0連続になります。スプラインのような滑らかな補間を使用すると、データの配列から関数をどのように表現するかによって、C1の連続性などを取得できます。
技術的には、データがC1またはC2曲線に対応しているかどうかを確認することはできませんが、それでも役立つ可能性のあることを行うことができます。
C1は連続一次導関数を意味します。したがって、導関数を数値で計算してから、導関数に大きなジャンプが見られる場合は、基礎となる曲線がC1ではないことが疑われる場合があります。(実際にそれを保証することはできませんが、それがC1でないか、いくつかの範囲外の導関数を持っていることを保証することはできます)。逆に、大きなジャンプがない場合は、データに適合する有界導関数を持つC1曲線があります。これは、実際にデータを生成した曲線と必ずしも同じではありません。
数値的に計算された二次導関数と同様のことを行って、そのC2ステータスを決定できます。(C1でない場合は、C2にすることはできません。そのため、そのテストが失敗した場合は、2番目のテストを忘れることができます。)
これは、xポイントが等間隔に配置されたC1の場合のC++での大まかな方法です。(物事が等間隔に配置されていない場合は、の計算を微調整する必要がありますs
)。
double y[N] = {0.56, 1, 12, 41, ..., 11, 0.11, 3, 23, 95 };
double max_abs_slope = 0;
double sum_abs_slope = 0;
double sum_abs_slope_sq = 0;
unsigned int imax=0;
for(unsigned int i=0; i<N-1; ++i )
{
double s = fabs( y[i+1]-y[i] );
sum_abs_slope += s;
sum_abs_slope_sq += s*s;
if(s>max_abs_slope) { max_abs_slope = s; imax = i; }
}
// We expect the max to be within three std-dev of the average.
double stddev = sqrt( (N*sum_abs_slope_sq - sum_abs_slope*sum_abs_slope)/(N*(N-1)) );
if( ( max_abs_slope - sum_abs_slope/(N-1) ) > 3 * stddev )
{
std::cout<<"There's an unexpectedly large jump in interval "<<imax<<std::endl;
}
else
{
std::cout<<"It seems smooth"<<std::endl;
}
ただし、とは異なるしきい値を使用する場合3*stddev
や、根本的な問題に関する知識に基づいて実際の制限を選択する場合、またはより厳密にする(> 3の値を使用)またはより厳密でない(<3)ことを選択する場合があります。
私はこのコードをテストしていないので、実行されないか、バグがある可能性があります。また、3*stddevがどの曲線にも意味があることも確認していません。これは非常に注意が必要です。