随机流理论和外汇 - 页 40

 
Prival >> :

请做转置程序,我在MQL中做不到。下面是一个在matcad中的例子。一个条件是事先不知道维数m和n,而且这个函数最好是反转的,也就是说,对哪个数组进行转置并不重要,当然它应该被多次调用并正常工作。

试试吧。



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 в AT

    double AT[];
    ArrayResize( AT, aRows * aCols );

    transposeMatrix( aRows, aCols, A, AT );

    // Получаем результат транспонирования B в BT

    double BT[];
    ArrayResize( BT, bRows * bCols );

    transposeMatrix( bRows, bCols, B, BT );
}
 

不,矩阵A和B必须转置,但你又生成了两个矩阵AT和BT,也就是说,你没有转置,而是做了相对于原矩阵转置的矩阵。

 

我没有看到任何区别。添加更多。


ArrayCopy( A, AT );
ArrayCopy( B, BT );

如果有必要的话,在原矩阵中得到转置结果。


虽然我只在需要转置矩阵的地方使用AT和BT,因为它们往往是成对出现的。

 
bstone писал(а)>>

我没有看到任何区别。添加更多。

如果有必要的话,在原矩阵中得到转置的结果。


虽然我只在需要转置矩阵的地方使用AT和BT,因为它们往往是成对出现的。

谢谢你提出复制AT和BT的想法,并在我需要的地方使用它们。我用铅笔检查一下是否能做到,但恐怕不行,因为卡尔曼滤波是迭代式的,一个相同的矩阵要转置几次,而不是在每个刻度上都要乘以它们。

但你的换位思考并不奏效。

你做错了--矩阵B和BT是二维的,即它们的等级=2,而你的是1。

插入 Print("-------",ArrayDimension(BT)); 答案是1

也就是说,你有一个一维数组,你没有将任何行与列对调。

 
Prival >> :

也就是说,你有一个一维数组,你没有将任何行与列对调。

不要急于下结论--数组外面是一维的,但里面是二维的 :)

 
bstone писал(а)>>

不要急于下结论--数组的外表是一维的,但内部是二维的 :)

理解然后飞所有的矩阵代数,这里又有一张matcad的图片。继续我的例子。

而且不仅仅是乘法,还有各种运算+自己的特定运算,这些都是矩阵代数所特有的。

如果在转置过程中违反了维度,那么一切都很糟糕,非常糟糕。

这不是一个简单的问题,虽然乍一看,有什么行和列的位置互换,但在这里,所以一看就知道不对头。

虽然我知道这个问题是可以解决的,但在MQL中,它是右手放在左耳上,上帝保佑我可以够到它。

 
Prival >> :

理解然后飞所有的矩阵代数,这里又是一张来自matcad的图片。继续我的例子。


私下里,相信我,我对矩阵代数非常精通。我已经为你提供了在MQL4方面的问题的解决方案。根本没有其他的解决方案,因为在MQL4中,只有第一个维度可以被动态管理。


为了得到一个完整的矩阵操作库,你需要重做你当前的版本,用不同的抽象来表示矩阵。具体来说,你需要从二维数组切换到线性数组。


思考一下matcad是如何存储矩阵的?是不是在线性数组中?还是你认为它把它们储存在二维的硬盘上?几个世纪以来,多维数组一直以线性方式存储在内存中,使用两种方式来分配数据:逐行或逐列。


如果你有一个3x2的矩阵,在内存中(一个线性数组),当逐行堆叠时,它将看起来像这样。{ A(1,1) A(1,2) A(2,1) A(2,2) A(3,1) A(3,2) }


因此,所有的矩阵操作必须使用这种数据组织。在现有的代码中,从二维索引到线性索引的过渡将不是一个问题。但你将完全控制动态矩阵的尺寸。

 

顺便说一下,以你最初想要的方式转置矩形矩阵的操作(即立即在原数组中转置)并不像乍看起来那么简单。事实上,这是一个复杂的问题,有许多棘手的算法来解决它。自1950年以来,编程之神一直试图有效地解决这个问题(最小的排列组合数、缓存定位、最小的额外内存等)。


所以不要因为无法解决这个问题而过于自责。

 
Prival >> :

但你的换位思考并不奏效。

你做错了 - 矩阵B和BT是二维的,即它们的等级=2,而你有1。

插入 Print("-------",ArrayDimension(BT)); 答案是1

也就是说,你有一个一维数组,你没有将任何行与列对调。

"矩阵的等级 "和 "数组的等级 "是否相同?在我的记忆中,一个矩阵的等级是它的小数的最高阶...但什么是 "数组的等级"...坦白说,我不知道...

 
bstone писал(а)>>

私下里,相信我,我对矩阵代数有很好的理解。我在MQL4方面为你提供了一个解决问题的方法。没有其他解决方案,因为在MQL4中,只有第一个维度可以动态控制。

这时,如果你能将数组转入和转出过程,那么问题又有了一个解决的办法,但MQL4也不允许这样做。我在上述模型的基础上创建了一个指标,摆脱了所有的转置、矩阵调用、矩阵指数化(SQRT(-1),但我无法避免)等。我在MQL4中实现了卡尔曼(2*2矩阵),但我已经花了3个多月的时间。而现在,如果我决定再增加一种货币,一切都要重新开始。而这是一个巨大的时间浪费。长期以来,我一直根据完成特定任务的速度来选择编程语言(我知道内存、效率、堆栈,曾经我也用汇编语言编程)。最主要的是时间,它是我们唯一的价值。

将等待MQL5 的到来。