public void Test_MatrixMultiply()
        {
            int errorCode = 0;

            // success?
            try {
                ILPerformer p       = new ILPerformer();
                double[]    data1   = new double[120];
                double[]    data2   = new double[120];
                double[]    results = new double[36] {
                    177840, 180120, 182400, 184680, 186960, 189240, 180120, 182440,
                    184760, 187080, 189400, 191720, 182400, 184760, 187120, 189480, 191840, 194200, 184680, 187080,
                    189480, 191880, 194280, 196680, 186960, 189400, 191840, 194280, 196720, 199160, 189240, 191720,
                    194200, 196680, 199160, 201640
                };
                for (int i = 0; i < 120; i++)
                {
                    data1[i] = i;
                    data2[i] = i * 2;
                }
                ILDA A            = new ILDA(data1, 6, 20);
                ILDA BR           = new ILDA(data2, 6, 20);
                ILDA ResultExpect = new ILDA(results, 6, 6);
                ILDA Result       = null;
                ILDA AR           = A.T.T;
                ILDA B            = BR.T;
                B.Detach();
                BR        = B.T.T;
                errorCode = 0;
                p.Tic();
                Result = ILMath.multiply(A, B);
                p.Toc();
                errorCode = 1;
                if (Result.Dimensions.NumberOfDimensions != 2)
                {
                    throw new Exception("Wrong number of results dimensions!");
                }
                errorCode = 2;
                if (Result.Dimensions[0] != 6 || Result.Dimensions[1] != 6)
                {
                    throw new Exception("Wrong result's size!");
                }
                errorCode = 3;
                if (!Result.Equals(ResultExpect))
                {
                    throw new Exception("Wrong results values!");
                }
                Info("Test_MatrixMultiplyDouble succeeded: phy/phy " + p.ToString() + "ms needed");
                errorCode = 4;
                p.Tic();
                if (!ResultExpect.Equals(ILMath.multiply(AR, BR)))
                {
                    throw new Exception("Wrong data value on ref/ref");
                }
                p.Toc();
                Info("Test_MatrixMultiplyDouble succeeded: ref/ref " + p.ToString() + "ms needed");
                // test if wrong dimensions throw exceptions
                try {
                    ILMath.multiply(A, AR);
                    throw new InvalidOperationException();
                } catch (Exception e) {
                    if (e is InvalidOperationException)
                    {
                        throw new Exception("Dimensions should be forced to match!");
                    }
                }
                data1 = new double[1000 * 2000];
                A     = new ILDA(data1, 1000, 2000);
                B     = new ILDA(data1, 2000, 1000);
                p.Tic();
                Result = ILMath.multiply(A, B);
                p.Toc();
                Info("Test_MatrixMultiply 1000x2000: phy/phy " + p.ToString() + "ms needed");
                Info("TODO: Implement test MatrixMultiply with reference storages!!");

                errorCode = 5;
                ILArray <float> fA = new ILArray <float>(new float[12] {
                    1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f, 10f, 11f, 12f
                }, 4, 3);
                ILArray <float> fB = new ILArray <float>(new float[12] {
                    17f, 18f, 19f, 20f, 21f, 22f, 23f, 24f, 25f, 26f, 27f, 28f
                }, 3, 4);
                ILArray <float> fRes = new ILArray <float>(new float[16] {
                    278f, 332f, 386f, 440f, 323f, 386f, 449f, 512f, 368f, 440, 512f, 584f, 413f, 494f, 575f, 656f
                }, 4, 4);
                if (ILMath.norm(fRes - ILMath.multiply(fA, fB)) > 1.0e-10)
                {
                    throw new Exception("Test_MatrixMultiply: invalid values detected!");
                }

                errorCode = 6;
                ILArray <complex> zA = ILMath.real2complex(ILMath.vector(1, 12), ILMath.vector(-1, -1, -12));
                ILArray <complex> zB = ILMath.real2complex(ILMath.vector(17, 28), ILMath.vector(-17, -1, -28));
                //{new complex (0 , 0.5560), new complex (0, 0.6640), new complex (0, 0.7720), new complex (0, 0.8800), new complex (0,  0.6460), new complex (0,  0.7720), new complex (0,  0.8980), new complex (0,  1.0240), new complex (0,  0.7360), new complex (0,  0.8800),new complex(0,1.0240),new complex(0,1.1680),new complex(0,0.8260),new complex(0,0.9880),new complex(0,1.1500),new complex(0,1.3120)}
                ILArray <complex> zRes = ILMath.real2complex(ILMath.zeros(1, 16), new ILArray <double>(new double[] { 556, 664, 772, 880, 646, 772, 898, 1024, 736, 880, 1024, 1168, 826, 988, 1150, 1312 }) * (-1));
                zA   = ILMath.reshape(zA, 4, 3);
                zB   = ILMath.reshape(zB, 3, 4);
                zRes = ILMath.reshape(zRes, 4, 4);

                if (ILMath.norm(zRes - ILMath.multiply(zA, zB)) > 1.0e-10)
                {
                    throw new Exception("Test_MatrixMultiply: invalid values detected!");
                }

                errorCode = 7;
                ILArray <fcomplex> cA   = ILMath.real2fcomplex(ILMath.vector(1, 12), ILMath.vector(-1, -1, -12));
                ILArray <fcomplex> cB   = ILMath.real2fcomplex(ILMath.vector(17, 28), ILMath.vector(-17, -1, -28));
                ILArray <fcomplex> cRes = ILMath.real2fcomplex(ILMath.zeros(1, 16), new ILArray <double>(new double[] { 556, 664, 772, 880, 646, 772, 898, 1024, 736, 880, 1024, 1168, 826, 988, 1150, 1312 }) * (-1));
                cA   = ILMath.reshape(cA, 4, 3);
                cB   = ILMath.reshape(cB, 3, 4);
                cRes = ILMath.reshape(cRes, 4, 4);

                if (ILMath.norm(cRes - ILMath.multiply(cA, cB)) > 1.0e-10)
                {
                    throw new Exception("Test_MatrixMultiply: invalid values detected!");
                }

                Success("Test_MatrixMultiply successful.");
            } catch (Exception e) {
                Error("Test_MatrixMultiply failed at step: " + errorCode + " Msg: " + e.Message);
            }
        }