Esempio n. 1
0
        public IMatrix uniteBlockOfSymmetric(cyMatrix LA, int a)
        {
            int firstRowCount = OriginA.RowCount / 2;
            int lastRowCount  = OriginA.RowCount - firstRowCount;

            int[] RowCount        = { firstRowCount, lastRowCount, lastRowCount };
            int[] ColCount        = { firstRowCount, firstRowCount, lastRowCount };
            int[] firstIndexOfRow = { 0, firstRowCount, firstRowCount };
            int[] firstIndexOfCol = { 0, 0, firstRowCount };

            IMatrix Array = new ArrayMatrix(OriginA.RowCount, OriginA.RowCount);

            double[][] array = Array.Array;
            //for (int i = 0; i < 3; i++)
            //{
            //    int row = RowCount[i];
            //    int col = ColCount[i];
            //    int firstRow = firstIndexOfRow[i];
            //    int firstCol = firstIndexOfCol[i];
            //    double[][] array1 = LA.blockMatrix1[i].Array;
            //    if (i == 0 || i == 2)
            //    {
            //        GetOriginalDiagData(array, array1, row, firstRow);
            //    }
            //    if (i == 1)
            //    {
            //        GetOriginalOrdinaryMatrixData(array, array1, row, col, firstRow, firstCol);
            //    }
            //}

            Parallel.For(0, 3, new Action <int>(delegate(int i)
            {
                int row           = RowCount[i];
                int col           = ColCount[i];
                int firstRow      = firstIndexOfRow[i];
                int firstCol      = firstIndexOfCol[i];
                double[][] array1 = LA.blockMatrix1[i].Array;
                if (i == 0 || i == 2)
                {
                    GetOriginalDiagData(array, array1, row, firstRow);
                }
                if (i == 1)
                {
                    GetOriginalOrdinaryMatrixData(array, array1, row, col, firstRow, firstCol);
                }
            }));
            return(new SymmetricMatrix(array));
        }
        public void inverse()
        {
            //
            int log = (int)Math.Log(coreNum, 2);//返回指定数字的对数

            //总共经过log级的分解完成并行计算
            if (log == 2)//4核
            {
                DateTime start = DateTime.Now;
                var      span  = DateTime.Now - start;
                //1级分裂
                cA = new cyMatrix(orignA, 2, 2);
                //start = DateTime.Now;
                //2级分裂
                cA1      = new cyMatrix(cA.blockMatrix1[0], 2, 2);
                cA2      = new cyMatrix(cA.blockMatrix1[2], 2, 2);
                DiagM    = new SymmetricMatrix[coreNum];
                DiagM[0] = cA1.blockMatrix1[0].Clone();
                DiagM[1] = cA1.blockMatrix1[2].Clone();
                DiagM[2] = cA2.blockMatrix1[0].Clone();
                DiagM[3] = cA2.blockMatrix1[2].Clone();
                Parallel.For(0, coreNum, (int i) =>
                {
                    DiagM[i] = DiagM[i].GetInverse();//.Inverse;
                });
                //var sssss = s11.Multiply(DiagM[0]);
                //并行求对角线上的块矩阵
                DiagQ = new SymmetricMatrix[coreNum];
                //通过使用任务来对代码进行并行化
                //创建任务
                var t0 = new Task(() => GenerateDiagQ0());
                var t1 = new Task(() => GenerateDiagQ1());
                var t2 = new Task(() => GenerateDiagQ2());
                var t3 = new Task(() => GenerateDiagQ3());
                t0.Start(); t1.Start(); t2.Start(); t3.Start();
                Task.WaitAll(t0, t1, t2, t3);//等待所有任务的完成


                //求逆
                Parallel.For(0, coreNum, (int i) =>
                {
                    if (i != 1)
                    {
                        DiagQ[i] = DiagQ[i].GetInverse();
                    }
                });

                #region 比下面这个多5ms,故省去
                //start = DateTime.Now; var b0 = new Task(() => GenenateBlock0());
                //var b1 = new Task(() => GenenateBlock1());
                //var b2 = new Task(() => GenenateBlock2());
                //var b3 = new Task(() => GenenateBlock3());
                //b0.Start(); b1.Start(); b2.Start(); b3.Start();
                //Task.WaitAll(b0, b1, b2, b3);//等待所有任务的完成
                //span = DateTime.Now - start;
                //Console.WriteLine(span.TotalMilliseconds + "ms融合3----");
                #endregion

                //GenenateBlockQ22();

                var c0 = new Task(() => GenenateBlockQ21());
                var c1 = new Task(() => GenenateBlockQ22());
                var c2 = new Task(() => GenenateBlock2());
                c0.Start(); c1.Start(); c2.Start(); Task.WaitAll(c0, c1, c2);

                cA1.blockMatrix1[0] = DiagQ[0];
                cA1.blockMatrix1[1] = cA1Q21;
                cA1.blockMatrix1[2] = cA1Q22;
                cA2.blockMatrix1[0] = DiagQ[2];
                cA2.blockMatrix1[2] = DiagQ[3];


                DiagM[0] = cA1.uniteBlockOfSymmetric(cA1, 1);
                DiagM[1] = cA2.uniteBlockOfSymmetric(cA2, 1);
                //var sss = DiagM[0].Multiply(cA.blockMatrix1[0]);
                var nt0 = new Task(() => GeneratenewDiagQ0());
                var nt1 = new Task(() => GeneratenewDiagQ1());
                nt0.Start();
                nt1.Start();
                Task.WaitAll(nt0, nt1);//等待所有任务的完成
                //Parallel.For(0, 2, (int i) =>
                //{
                //    DiagQ[i] = DiagQ[i].GetInverse();//.Inverse;
                //});
                DiagQ[0] = DiagQ[0].GetInverse();

                #region 比下面这个直接按顺序计算多15ms,故省去
                //start = DateTime.Now;
                //var nb0 = new Task(() => GeneratenewBlock0());
                //var nb1 = new Task(() => GeneratenewBlock1());
                //nb0.Start(); nb1.Start();
                //Task.WaitAll(nb0, nb1);//等待所有任务的完成
                //span = DateTime.Now - start;
                //Console.WriteLine(span.TotalMilliseconds + "ms融合30000");
                #endregion


                var task0 = new Task(() => GeneratenewBlockQ22());
                var task1 = new Task(() => GeneratenewBlockQ21());
                task0.Start(); task1.Start();
                Task.WaitAll(task0, task1);

                cA.blockMatrix1[0] = DiagQ[0];
                cA.blockMatrix1[1] = Q21;
                cA.blockMatrix1[2] = Q22;

                invA = cA.uniteBlockOfSymmetric(cA, 1);
                //var sssss0 = invA.Multiply(orignA);
            }
        }
        public void inverse()
        {
            DateTime start = DateTime.Now;
            var      span  = DateTime.Now - start;

            //1级分裂
            cA = new cyMatrix(orignA, 2, 2);

            SymmetricMatrix q22 = new SymmetricMatrix(cA.blockMatrix1[2].Clone().Array);
            IMatrix         q21 = cA.blockMatrix1[1].Clone();
            SymmetricMatrix Q   = q22.Inverse();

            SymmetricMatrix q11 = new SymmetricMatrix(cA.blockMatrix1[0].Minus(q21.Transposition.Multiply(Q).Multiply(q21)).Array);

            Q11 = q11.Inverse();    //.GetInverse();
            var task0 = new Task(() => GetQ21(q21, Q));
            var task1 = new Task(() => GetQ22(q21, Q));

            task0.Start(); task1.Start();

            Task.WaitAll(task0, task1);

            cA.blockMatrix1[0] = Q11;
            cA.blockMatrix1[1] = Q21;
            cA.blockMatrix1[2] = Q22;
            invA = cA.uniteBlockOfSymmetric(cA, 1);
            var sssss0 = invA.Multiply(orignA);

            #region hide
            ////start = DateTime.Now;
            ////2级分裂
            //cA1 = new cyMatrix(cA.blockMatrix1[0], 2, 2);
            //cA2 = new cyMatrix(cA.blockMatrix1[2], 2, 2);
            //DiagM = new SymmetricMatrix[coreNum];
            //DiagM[0] = cA1.blockMatrix1[0].Clone();
            //DiagM[1] = cA1.blockMatrix1[2].Clone();
            //DiagM[2] = cA2.blockMatrix1[0].Clone();
            //DiagM[3] = cA2.blockMatrix1[2].Clone();
            ////var s11 = DiagM[0].Clone();
            //Parallel.For(0, coreNum, (int i) =>
            //{
            //    DiagM[i] = DiagM[i].GetInverse();//.Inverse;
            //});
            ////var sssss = s11.Multiply(DiagM[0]);
            ////并行求对角线上的块矩阵
            //DiagQ = new SymmetricMatrix[coreNum];
            ////通过使用任务来对代码进行并行化
            ////创建任务
            //var t0 = new Task(() => GenerateDiagQ0());
            //var t1 = new Task(() => GenerateDiagQ1());
            //var t2 = new Task(() => GenerateDiagQ2());
            //var t3 = new Task(() => GenerateDiagQ3());
            //t0.Start(); t1.Start(); t2.Start(); t3.Start();
            //Task.WaitAll(t0, t1, t2, t3);//等待所有任务的完成

            ////var q0 = DiagQ[0].Clone();
            ////var q1 = DiagQ[1].Clone();
            ////var q2 = DiagQ[2].Clone();
            ////var q3 = DiagQ[3].Clone();

            ////求逆
            //Parallel.For(0, coreNum, (int i) =>
            //{
            //    DiagQ[i] = DiagQ[i].GetInverse();//.Inverse;
            //});

            ////var r0 = q0.Multiply(DiagQ[0]);
            ////var r1 = q1.Multiply(DiagQ[1]);
            ////var r2 = q2.Multiply(DiagQ[2]);
            ////var r3 = q3.Multiply(DiagQ[3]);

            //#region 比下面这个多5ms,故省去
            ////start = DateTime.Now; var b0 = new Task(() => GenenateBlock0());
            ////var b1 = new Task(() => GenenateBlock1());
            ////var b2 = new Task(() => GenenateBlock2());
            ////var b3 = new Task(() => GenenateBlock3());
            ////b0.Start(); b1.Start(); b2.Start(); b3.Start();
            ////Task.WaitAll(b0, b1, b2, b3);//等待所有任务的完成
            ////span = DateTime.Now - start;
            ////Console.WriteLine(span.TotalMilliseconds + "ms融合3----");
            //#endregion

            //var xxx = DiagM[1].Plus(DiagM[1].Multiply(cA1.blockMatrix1[1]).Multiply(DiagQ[0]).Multiply(cA1.blockMatrix1[1].Transposition).Multiply(DiagM[1]));
            //var xxx2 = DiagM[3].Plus(DiagM[3].Multiply(cA2.blockMatrix1[1]).Multiply(DiagQ[2]).Multiply(cA2.blockMatrix1[1].Transposition).Multiply(DiagM[3]));

            //var c0 = new Task(() => GenenateBlock0());
            //var c2 = new Task(() => GenenateBlock2());
            //c0.Start(); c2.Start(); Task.WaitAll(c0, c2);

            //cA1.blockMatrix1[0] = DiagQ[0];
            ////cA1.blockMatrix1[2] = DiagQ[1];

            //cA2.blockMatrix1[0] = DiagQ[2];
            ////cA2.blockMatrix1[2] = DiagQ[3];

            ////var ooo = cA1.blockMatrix1[2].Minus(xxx);

            ////DiagM[0] = cA1.uniteBlockOfSymmetric(cA1,1);
            ////DiagM[1] = cA2.uniteBlockOfSymmetric(cA2,1);

            ////var ss = DiagM[0].Multiply(cA.blockMatrix1[0]);
            ////var ss1 = DiagM[1].Multiply(cA.blockMatrix1[2]);
            //cA1.blockMatrix1[2] = xxx;
            //cA2.blockMatrix1[2] = xxx2;

            //DiagM[0] = cA1.uniteBlockOfSymmetric(cA1, 1);
            //DiagM[1] = cA2.uniteBlockOfSymmetric(cA2, 1);
            //var sss = DiagM[0].Multiply(cA.blockMatrix1[0]);
            //var nt0 = new Task(() => GeneratenewDiagQ0());
            //var nt1 = new Task(() => GeneratenewDiagQ1());
            //nt0.Start();
            //nt1.Start();
            //Task.WaitAll(nt0, nt1);//等待所有任务的完成
            //Parallel.For(0, 2, (int i) =>
            //{
            //    DiagQ[i] = DiagQ[i].GetInverse();//.Inverse;
            //});


            //#region 比下面这个直接按顺序计算多15ms,故省去
            ////start = DateTime.Now;
            ////var nb0 = new Task(() => GeneratenewBlock0());
            ////var nb1 = new Task(() => GeneratenewBlock1());
            ////nb0.Start(); nb1.Start();
            ////Task.WaitAll(nb0, nb1);//等待所有任务的完成
            ////span = DateTime.Now - start;
            ////Console.WriteLine(span.TotalMilliseconds + "ms融合30000");
            //#endregion
            //var xxxx = DiagM[1].Plus(DiagM[1].Multiply(cA.blockMatrix1[1]).Multiply(DiagQ[0]).Multiply(cA.blockMatrix1[1].Transposition).Multiply(DiagM[1]));
            //GeneratenewBlock0();

            //cA.blockMatrix1[0] = DiagQ[0];
            ////cA.blockMatrix1[2] = DiagQ[1];
            ////invA = cA.uniteBlockOfSymmetric(cA, 1);
            ////var ssss = invA.Multiply(orignA);

            ////var oooo = cA1.blockMatrix1[2].Minus(xxx);
            //cA.blockMatrix1[2] = xxxx;
            //invA = cA.uniteBlockOfSymmetric(cA, 1);
            ////var sssss0 = invA.Multiply(orignA);
            #endregion
        }