void transposeMatrix(int rows,int cols,double a[],double& t[]){for(int i =0; i < rows; i++){for(int j =0; j < cols; j++){
t[ j * rows + i ]= a[ i * cols + j ];}}}void example(){int m =5;int n =3;int aRows = m +1;int aCols =1;double A[];ArrayResize( A, aRows * aCols );for(int i =0; i <= m; i++) A[ i ]= i;int bRows = m +1;int bCols = n +1;double B[];ArrayResize( B, bRows * bCols );for( i =0; i <= m; i++){for(int j =0; j <= n; j++) B[ i * bCols + j ]= i + j;}// Получаем результат транспонирования A в ATdouble AT[];ArrayResize( AT, aRows * aCols );
transposeMatrix( aRows, aCols, A, AT );// Получаем результат транспонирования B в BTdouble BT[];ArrayResize( BT, bRows * bCols );
transposeMatrix( bRows, bCols, B, BT );}
トランスポーズプロシージャをやってください、MQLでできないんです。以下は、matcadでの例です。条件としては、mとnの次元があらかじめわからないこと、関数が逆数であること、つまり、どの配列を転置してもよいこと、もちろん、複数回呼ばれて正しく動作すること、があげられます。
試してみてください。
いいえ,行列AとBは転置されなければなりませんが,あなたはさらに2つの行列ATとBTを生成しました。つまり,転置したのではなく,元の行列に対して転置された行列を作ったのです
違いがわからない。さらに追加する。
を計算し,必要なら元の行列の転置結果を得ます。
ただ、ATとBTはペアで使うことが多いので、転置行列が必要なところだけ使いますが。
違いがわからない。さらに追加する。
を計算し,必要なら元の行列の転置結果を得ます。
転置行列はペアで行くことが多いので、転置行列が必要なところだけATとBTを使うことになりますが。
ATとBTをコピーして必要なところに使うというアイデア、ありがとうございました。出来るかどうか鉛筆で確認してみますが、カルマンフィルターは反復処理であり、1つの同じ行列を何度も転置し、1目盛りごとに掛け合わせるわけではないので、無理だと思います。
しかし、あなたの転置はうまくいかなかった。
行列BとBTは2次元、つまりランク=2であり、あなたは1を持っています。
Insert Print("-------",ArrayDimension(BT)); 答えは1です。
つまり、1次元の配列で、行と列を入れ替えていない場合です。
つまり、1次元の配列で、行と列を入れ替えていない場合です。
配列は外側が1次元で、内側が2次元であるため、結論を急がないでください :)
配列は見た目は一次元、中身は二次元なのです :)
次に、すべての行列代数を理解するために、ここで再びmatcadから画像を表示します。私の例の続きです。
で、乗算だけでなく、あらゆる演算+行列代数に特有の演算がある。
もし、転置の際に次元性が損なわれると、すべてが悪い、非常に悪いことになる。
それは、一見すると、そこにある行と列が場所を交換するものですが、単純な問題ではなく、ここでは一見すると、それが判明しません。
この問題は確実に解決できるのですが、MQLでは左耳に右手で、手が届かないのです。
次に、すべての行列代数を理解するために、ここで再びmatcadからの画像を示します。私の例の続きです。
プライベートの話ですが、信じてください、私は行列代数にとても詳しいんです。MQL4という観点から問題の解決策を提示させていただきました。MQL4では、1次元目しか動的に管理できないため、他に解決策がありません。
行列演算の完全なライブラリを得るためには、現在のバージョンを、行列を表現するための別の抽象化で動作するように作り直す必要があります。具体的には、2次元配列から線形配列に変更する必要があります。
matcadが行列を保存する方法を考えてみてください。リニアアレーにはないのでしょうか?それとも、2次元のハードディスクに保存しているのでしょうか?多次元配列は何世紀にもわたって、行単位と列単位の2つの方法でデータを分配し、直線的にメモリに格納されてきた。
3x2の行列を、メモリ上(線形配列)で、一行ずつ積み上げると、次のようになります。{ a(1,1) a(1,2) a(2,1) a(2,2) a(3,1) a(3,2) }.
したがって、すべての行列演算はこのデータ構成を使用する必要があります。既存コードの2次元インデックスから線形インデックスへの移行は問題ないでしょう。しかし、動的なマトリックスの次元を完全に制御することができます。
ところで,矩形行列を本来欲しい形で(つまり元の配列の中ですぐに)転置する操作は,一見したところ,それほど些細なことではないようです.実は、この問題は複雑で、それを解くためのトリッキーなアルゴリズムがたくさんあります。プログラミングの神様は、1950年以来、それを効果的に解決しようと試みてきた(最小順列数、キャッシュロカリティ、最小追加メモリなど)。
だから、解けなかったからといって、あまり自分を追い込まないことです。
しかし、あなたの転置はうまくいかなかった。
行列BとBTは2次元であり、ランクは2であり、ランクは1です。
Insert Print("-------",ArrayDimension(BT)); 答えは1です。
つまり、1次元の配列で、行と列を入れ替えていない場合です。
行列のランク」と「配列のランク」は同じですか?私の記憶では、行列のランクは、そのマイナーの最高位である...。でも、「配列のランク」ってなんだろう...ぶっちゃけ、わからない...。
プライベートの話ですが、信じてください、私は行列代数を非常によく理解しているのです。MQL4という観点で解決策を提示したのです。MQL4では、1次元目しか動的に制御できないので、他に解決策はありません。
ここで、プロシージャとの間で配列の受け渡しができれば、もう一つ問題が解決するのですが、MQL4ではそれもできません。上記のモデルを元にインジケータを作り、転置、行列呼び出し、行列の累乗(SQRT(-1)、でも避けられない)などを全て取り除き、MQL4(2*2行列)でKalmanを実装したが3ヶ月以上かかってしまった。そして今、もう1つ通貨を追加しようと思ったら、また同じことの繰り返しです。そして、それは大きな時間の浪費です。私は長い間、与えられたタスクを達成するスピードに基づいてプログラミング言語を選択してきました(そして、メモリ、効率、スタックについて知っています、むかしはアセンブラでプログラミングしていました)。メインは時間、それしか価値がない。
MQL5を待ちます。