係数算出アルゴリズムについて

[戻る]
PAG 2008/12/24(水) 12:52:26
[開発環境]===========
・VisualStudio2008Std
・言語:VC++
・.netFW:3.5
=====================

始めまして。
算数的な質問で申し訳ありません。
以下の(式1)に対して、(式2)が成立するような、係数(C)の算出方法を考察中です。

(式1)

Σ1 = C1*VA1 + C2*VB1 + .... Cn*V⒳1
Σ2 = C1*VA2 + C2*VB2 + .... Cn*V⒳2
        :
Σm = C1*VAm + C2*VBm + .... Cn*V⒳m


(式2)
Σ1 =(≒) Σ2 =(≒) .... Σm

(注釈)-----------------------------------------------------------
Σ    : 行要素積算値
V⒳    : 列要素数値        (否変動値)
m    : 行INDEX
n    : 列INDEX
C    : 各列要素毎の係数        (可変動値)(C>=0)
-----------------------------------------------------------------

現状、データ点数の少ない場合には、Excellのアドイン(ソルバー)を使用し、
多い場合には、Cにて以下のような関数を作成し対応しています。


この関数からは、それらしい結果は得られるのですが、データ点数、
精度を求めると膨大な処理時間となってしまいます。

これに変わって、1係数1式で求まるような数学的な手法は無いものかと
考えています。

クリティカルな答えではなくとも、上式の開放に適した手法や
とっかかりとなるキーワードなど、ご存知の方は是非、ご教示お願いします。





(作成関数)---------------------------------------------------
C毎にCの値を適当に小さな単位で変動させ、
所望状態との誤差を一回一回評価。
最も誤差が小さくなるあたり(適当)
の(C)の組み合わせを取得。
---------------------------------------------------------------
double Coef[列数];
double CurrentDiff;        //変動させるC係数設定予定値

for(;;){
    for(i=...列ループ){
        for(j=...列毎C値変動ループ){
        
            現挑戦値 = 1/(10^Decimal) 
            Coef[i] = 現挑戦値;
            CurrentDiff = 『誤差測定関数』;
        
            if(CurrentDiffが今回iループ内で最小なら){
                C採用候補値更新;
            }
    }
    Coef[i]=C採用候補値;
    
    switch(前回誤差と今回誤差比較して...){
    
    case: (同じ) break;
    case: (誤差が許容量(適当)以下) break;

    }
}
---------------------------------------------------------------

PAG 2008/12/24(水) 12:54:53
(文字化けのため、式のみ再投稿)


(式1)

Σ1 = C1*VA1 + C2*VB1 + .... Cn*V(x)1
Σ2 = C1*VA2 + C2*VB2 + .... Cn*V(x)2
        :
Σm = C1*VAm + C2*VBm + .... Cn*V(x)m


(式2)
Σ1 =(≒) Σ2 =(≒) .... Σm

(注釈)-----------------------------------------------------------
Σ    : 行要素積算値
V(x)    : 列要素数値        (否変動値)
m    : 行INDEX
n    : 列INDEX
C    : 各列要素毎の係数        (可変動値)(C>=0)
-----------------------------------------------------------------

wclrp ( 'o') 2008/12/24(水) 19:57:42
正直なところ俺はどういう計算なのか判っていないので推測です。

データ数が2倍になると計算量は4倍になるタイプかな。

結果の比較を除けば独立性が高いからハイパースレッディングで
マルチスレッドにすると1.8倍くらいになりそう。数値にあまり根拠ないけど。
でも面倒だな。やりたくないな。

Streaming SIMD Extensions
doubleと精度変わるしデータの並び順が重要だし速くなるかどうかわからんし
大変なのでやりたくないな。

中断する閾値みたいなの設けてないの。
例えば
Σ1 = 略
Σ2 = 略
Σ1とΣ2の差が閾値より大きかったらΣ3の計算をあきらめるとか。

yoh2 [E-Mail] 2008/12/24(水) 23:14:09
この式、Σを移項すれば単純なn+1元一次連立方程式の形になるように見えます。
未知変数がCi (i = 1 .. n) とΣ (式2により、Σiは単一の変数Σに代表させる
ことができる) の方程式です。
mとnの関係によって、解が一意に求められないような場合でも、掃き出し方の要領で
式をかなり単純化できるのではないでしょうか。

ホウジョウウサギ 2008/12/25(木) 09:46:43
全く的外れかもしれませんが,たとえばm=n=2で考えると
Vが対角行列みたいな(?)形でもないと
「C1=C2=0 が最も良い答え」ということになりそうなのですが,
Excellや作成された関数では本当に「それらしい答え」が出るのですか…?


C1〜Cnの初期値(どうやって決める?)
 ↓計算開始すると
C1〜Cnの値をとにかく小さくしていくようなループ
 ↓閾値に達したところで
そのときのC1〜Cnの値を結果として出力


ということが起こりそうに思えます.
その結果=それらしい ということであれば良いのでしょうけど.

yoh2 [E-Mail] 2008/12/25(木) 23:03:51
> 「C1=C2=0 が最も良い答え」ということになりそうなのですが,

そういえばそうですね。
すべての式の定数項が0になるので、解が一意に定まるとしたらすべて0以外ありえなくなります
ね。
ということは、複数の解を持つのが前提で、追加でどういった解が望ましいかの条件があるので
しょうか。

# もしかして 「C >= 0」 は 「C > 0」 の間違い?

ホウジョウウサギ 2008/12/26(金) 11:10:58
行列Vのほとんどの要素が0で少数だけが0以外の値を持っているのだとすれば,
Vの各列で「1個だけ0以外の値である」列に対応するCの値だけが値を持つ結果になるか
と思います.
(列要素が全て0の場合はCは不定)
で,そのような「全部のCが0にならない」ような問題を扱っているのだとして,誤差関
数の最小化問題でしょうから

>C毎にCの値を適当に小さな単位で変動させ、
>所望状態との誤差を一回一回評価。

というようなことは もっと一般的な数値計算の手法を使えば速くなるのではないでしょ
うか.

誤差評価関数が最小二乗法みたいなのならば,
線形のとき → 特異値分解
非線形のとき → Newton法,Marquardt法,NelderのSimplex法…
とかが一般的?

古いスレッドには追加発言できません。