private void FirstPhaseHalfPivot(MatrixEquation <double> eq)
        {
            //Pierwsza faza eliminacji Gaussa, z częściowym wyborem elementu podstawowego
            //Tworzy z macierzy A macierz trójkątną górną oraz dzieli wiersze tak, aby uzyskać jedynki wiodące
            //Przenosi operacje na macierz B
            for (int i = 0; i < eq.A.ColCount; i++)
            {
                //Wybór wiodącego elementu
                int max = FindMaxInColumn(eq.A, i, i, eq.A.RowCount);

                eq.A.SwapRows(i, max);
                eq.B.SwapRows(i, max);

                if (eq.A.ValueMatrix[i][i].CompareTo(MatrixDouble.ONE) != 0) //Pierwsza optymalizacja - jeśli wiodąca liczba jest jedynką, to wiersz nie jest już mnożony
                {
                    eq.B.ValueMatrix[i] = Matrix <double> .MultiplyRow(eq.B.ValueMatrix[i], (eq.A.ValueMatrix[i][i].GetInverse()));

                    eq.A.ValueMatrix[i] = Matrix <double> .MultiplyRow(eq.A.ValueMatrix[i], (eq.A.ValueMatrix[i][i].GetInverse()));
                }

                for (int j = i + 1; j < eq.A.RowCount; j++)
                {
                    if (eq.A.ValueMatrix[j][i].CompareTo(MatrixDouble.ZERO) != 0)
                    {
                        eq.B.ValueMatrix[j] = Matrix <double> .SubtractRows(eq.B.ValueMatrix[j], Matrix <double> .MultiplyRow(eq.B.ValueMatrix[i], eq.A.ValueMatrix[j][i]));

                        eq.A.ValueMatrix[j] = Matrix <double> .SubtractRows(eq.A.ValueMatrix[j], Matrix <double> .MultiplyRow(eq.A.ValueMatrix[i], eq.A.ValueMatrix[j][i]));
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// 用MatrixEquation得到的预测值
        /// </summary>
        /// <param name="str">实验号</param>
        /// <returns>预测值</returns>
        public static List <DataValue> getAllPredictValue(String str)
        {
            List <DataValue> lists = new List <DataValue>();

            List <double> a = SqlData.sqlGetData("dbo.小麦质量特性参数数据表", "CanNumberValue", str);

            List <DateTime> dateTime = SqlData.sqlDataDate("dbo.小麦质量特性参数数据表", "Date", str);

            List <double> grainTemp    = SqlData.sqlDataDoubleValue("dbo.小麦质量特性参数数据表", "GrainTemp", str);
            List <double> WaterValue   = SqlData.sqlDataDoubleValue("dbo.小麦质量特性参数数据表", "Water", str);
            String        canShuNumber = SqlData.getCanShuNumber("dbo.小麦参数实验总概括表", "CanShuNumber", str);
            String        canShuName   = SqlData.getCanShuName("dbo.小麦参数名表", "CanShuName", canShuNumber);

            double[]      douTemp = grainTemp.ToArray();
            double[]      col0    = a.ToArray();
            DateTime[]    date    = dateTime.ToArray();
            double[]      water   = WaterValue.ToArray();
            List <double> dayDou  = new List <double>();//将有数据的日期转换为double类型

            for (int i = 0; i < date.Length; i++)
            {
                dayDou.Add(date[i].ToOADate());
            }

            List <double> doubleDay = new List <double>();

            for (double j = dayDou[0]; j <= dayDou[dayDou.Count - 1]; j++)
            {
                doubleDay.Add(j);
            }
            double[] ceshi = spline.setSplineData(dayDou.ToArray(), col0, doubleDay.ToArray());//实际值

            MatrixEquation mart = new MatrixEquation();

            double[] ceshi2 = mart.MultiLine(dayDou.ToArray(), col0, col0.Length, 3);
            int      index  = -1;
            DateTime dDay   = date[0];

            for (int i = 0; i < doubleDay.Count; i++)
            {
                DataValue datapoint = new DataValue();
                double    y1        = ceshi2[0] + ceshi2[1] * doubleDay[i] + ceshi2[2] * doubleDay[i] * doubleDay[i] + ceshi2[3] * doubleDay[i] * doubleDay[i] * doubleDay[i];
                datapoint.PredictData = y1;

                if (i % 30 == 0)
                {
                    index++;
                }
                datapoint.GrainTemp    = douTemp[index];
                datapoint.Water        = water[index];
                datapoint.date         = dDay.AddDays(1);
                datapoint.CanShuNumber = canShuNumber;
                datapoint.yLable       = canShuName;
                dDay = datapoint.date;
                datapoint.ChaValue = ceshi[i] - y1;
                datapoint.Y        = ceshi[i];
                lists.Add(datapoint);
            }
            return(lists);
        }
        public void Perform(MatrixEquation <double> eq)
        {
            Matrix <double> oldVector = new Matrix <double>(eq.B);

            for (int i = 0; i < oldVector.RowCount; i++)
            {
                oldVector.ValueMatrix[i][0] = MatrixDouble.ZERO;
            }

            Matrix <double> newVector = new Matrix <double>(eq.B);

            int iterations = 0;

            while (Matrix <double> .GetNormOfDiffrence(oldVector, newVector) > this.precision)
            {
                oldVector = new Matrix <double>(newVector);

                iterations++;

                for (int i = 0; i < eq.A.RowCount; i++)
                {
                    GaussSeidelIteration(eq, newVector, i);
                }
            }

            eq.X = newVector;

            return;
        }
        public void Perform(MatrixEquation <double> eq)
        {
            FirstPhaseHalfPivot(eq);
            SecondPhase(eq);

            eq.X = eq.B;

            return;
        }
Beispiel #5
0
        public void Perform(MatrixEquation <double> eq)
        // Eliminacja Gaussa z częściowym wyborem elementu
        // Brak optymalizacji
        {
            FirstPhaseHalfPivot(eq);
            SecondPhase(eq);

            eq.X = eq.B;

            return;
        }
        public LinearFunction(double[] arguments, double[] values)
        {
            Matrix <double> A = GetAMatrix(arguments);
            Matrix <double> B = GetBMatrix(arguments, values);

            MatrixEquation <double> Eq = new MatrixEquation <double>(A, null, B);

            Eq.Evaluate(new Matrix.MatrixEquasionEvaluator.GaussianHalfPivot());

            b = Eq.X.ValueMatrix[0][0].Evaluate();
            a = Eq.X.ValueMatrix[1][0].Evaluate();
        }
Beispiel #7
0
        /// <summary>
        /// 第一步:组固定参数的方法方程
        /// </summary>
        /// <param name="inputs"></param>
        /// <returns></returns>
        private static List <MatrixEquation> Setp1ComposeConstNormaEqualtion(List <AdjustObsMatrix> inputs)
        {
            List <MatrixEquation> normals = new List <MatrixEquation>();

            //step 1: 分离易变参数
            foreach (var obsMatrix in inputs)
            {
                MatrixEquation ne = obsMatrix.BuildConstParamNormalEquation();
                normals.Add(ne);
            }
            return(normals);
        }
Beispiel #8
0
        private void SecondPhase(MatrixEquation <double> eq)
        {
            //Druga faza eliminacji Gaussa
            //Sprowadza macierz A do macierzy jednostkowej
            //Po tej operacji macierz B to wyliczony X, błąd to | ||B|| - ||X|| |
            for (int i = eq.A.ColCount - 1; i >= 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    eq.B.ValueMatrix[j] = Matrix <double> .SubtractRows(eq.B.ValueMatrix[j], Matrix <double> .MultiplyRow(eq.B.ValueMatrix[i], eq.A.ValueMatrix[j][i]));

                    eq.A.ValueMatrix[j] = Matrix <double> .SubtractRows(eq.A.ValueMatrix[j], Matrix <double> .MultiplyRow(eq.A.ValueMatrix[i], eq.A.ValueMatrix[j][i]));
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// 构建不变参数的法方程。不变参数由第二参数构成
        /// 注意:需要控制不变参数的增减问题。
        /// 基本思路:增加则插入,减少则删除,通过参数名称来控制。
        /// </summary>
        /// <returns></returns>
        public MatrixEquation BuildConstParamNormalEquation()
        {
            //观测值权阵设置,对已知量赋值
            Matrix L               = new Matrix((IMatrix)this.Observation);
            Matrix QL              = new Matrix(this.Observation.InverseWeight);
            Matrix PL              = new Matrix(QL.GetInverse());
            Matrix A               = new Matrix(this.Coefficient);
            Matrix AT              = A.Trans;
            Matrix B               = new Matrix(this.SecondCoefficient);
            Matrix BT              = B.Trans;
            Matrix X0              = this.HasApprox ? new Matrix(this.ApproxVector, true) : null;
            Matrix Y0              = this.HasSecondApprox ? new Matrix(this.SecondApproxVector, true) : null;
            Matrix D               = this.HasFreeVector ? new Matrix(this.FreeVector, true) : null;
            int    obsCount        = L.RowCount;
            int    fixedParamCount = B.ColCount;
            int    freedom         = obsCount - fixedParamCount;

            //观测值更新
            Matrix lxy = L - (A * X0 + B * Y0 + D); //采用估值计算的观测值小量

            Matrix ATPL = AT * PL;
            //法方程
            Matrix Na      = ATPL * A;
            Matrix Nab     = AT * PL * B;
            Matrix InverNa = Na.Inversion;
            Matrix J       = A * InverNa * AT * PL;
            Matrix I       = Matrix.CreateIdentity(J.RowCount);
            Matrix B2      = (I - J) * B; //新的系数阵 Ac, 原文中为 B波浪~
            Matrix B2T     = B2.Trans;
            Matrix B2TPL   = B2T * PL;
            Matrix NofB2   = B2TPL * B2;
            Matrix UofB2   = B2TPL * lxy;

            NofB2.ColNames = this.SecondParamNames;
            NofB2.RowNames = this.SecondParamNames;

            UofB2.RowNames = this.SecondParamNames;
            UofB2.ColNames = new List <string>()
            {
                "ConstParam"
            };


            var ne = new MatrixEquation(NofB2, UofB2);

            return(ne);
        }
        private void GaussSeidelIteration(MatrixEquation <Double> eq, Matrix <Double> newVector, int i)
        {
            IMatrixDataType <double> x = new MatrixDouble(0);

            for (int j = 0; j < eq.A.ColCount; j++)
            {
                if (i != j)
                {
                    x = (x.Add(eq.A.ValueMatrix[i][j].Multiply(newVector.ValueMatrix[j][0])));
                }
            }
            x = x.Multiply(MatrixDouble.MINUSONE);
            x = x.Add(eq.B.ValueMatrix[i][0]);
            x = x.Divide(eq.A.ValueMatrix[i][i]);

            newVector.ValueMatrix[i][0] = x;
        }
        private void SecondPhase(MatrixEquation <double> eq)
        {
            //Druga faza eliminacji Gaussa
            //Sprowadza macierz A do macierzy jednostkowej
            for (int i = eq.A.ColCount - 1; i >= 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    if (eq.A.ValueMatrix[j][i].CompareTo(MatrixDouble.ZERO) != 0)
                    {
                        eq.B.ValueMatrix[j] = Matrix <double> .SubtractRows(eq.B.ValueMatrix[j], Matrix <double> .MultiplyRow(eq.B.ValueMatrix[i], eq.A.ValueMatrix[j][i]));

                        eq.A.ValueMatrix[j] = Matrix <double> .SubtractRows(eq.A.ValueMatrix[j], Matrix <double> .MultiplyRow(eq.A.ValueMatrix[i], eq.A.ValueMatrix[j][i]));
                    }
                }
            }
        }
Beispiel #12
0
        public List <DaoGuZhiLiangTeXingModel> getAllPredictData(List <DaoGuZhiLiangTeXingModel> models)
        {
            string xLabel = models[0].xLabel;
            string yLabel = models[0].canShuName;
            List <DaoGuZhiLiangTeXingModel> allModels = getAllData(models);

            double[]      douY    = new double[allModels.Count];
            double[]      douX    = new double[allModels.Count];
            List <double> douAllX = new List <double>();

            //double[] douAllY;

            for (int i = 0; i < allModels.Count; i++)
            {
                douX[i] = Convert.ToDouble(allModels[i].xData);
                douY[i] = Convert.ToDouble(allModels[i].yData);
            }
            for (double i = douX[0]; i <= douX[allModels.Count - 1]; i++)
            {
                douAllX.Add(i);
            }
            MatrixEquation mart = new MatrixEquation();

            double[] xiShu = mart.MultiLine(douX, douY, douY.Length, 3);

            List <DaoGuZhiLiangTeXingModel> allPredictModels = new List <DaoGuZhiLiangTeXingModel>();

            for (int i = 0; i < douAllX.Count; i++)
            {
                DaoGuZhiLiangTeXingModel model = new DaoGuZhiLiangTeXingModel();

                double y = xiShu[0] + xiShu[1] * douAllX[i] + xiShu[2] * douAllX[i] * douAllX[i] + xiShu[3] * douAllX[i] * douAllX[i] * douAllX[i];
                model.xData = douAllX[i].ToString();
                model.yData = y.ToString();
                allPredictModels.Add(model);
            }
            for (int i = 0; i < allPredictModels.Count; i++)
            {
                allPredictModels[i].high            = getMax(convert(allPredictModels));
                allPredictModels[i].low             = getMin(convert(allPredictModels));
                allPredictModels[i].predictChaValue = Convert.ToDouble(allModels[i].yData) - Convert.ToDouble(allPredictModels[i].yData);
                allPredictModels[i].xLabel          = xLabel;
                allPredictModels[i].canShuName      = yLabel;
            }
            return(allPredictModels);
        }
Beispiel #13
0
        private void button_randomGen_Click(object sender, EventArgs e)
        {
            DateTime from  = DateTime.Now;
            int      order = 100;
            int      row   = this.namedIntControl_row.GetValue();
            int      col   = this.namedIntControl_col.GetValue();
            var      name  = namedStringControl_name.GetValue();

            double[][]    matrix   = MatrixUtil.CreateRandom(row, col);
            Matrix        mat      = new Matrix(matrix);
            var           prefix   = namedStringControl_prefName.GetValue();
            List <string> rowNames = new List <string>();

            for (int i = 0; i < row; i++)
            {
                rowNames.Add(prefix + i.ToString("000"));
            }
            List <string> colNames = new List <string>();

            for (int i = 0; i < col; i++)
            {
                colNames.Add(prefix + i.ToString("000"));
            }

            mat.RowNames = rowNames;
            mat.ColNames = colNames;


            double[][] rigth = MatrixUtil.CreateRandom(row, 1);
            Matrix     rmat  = new Matrix(rigth);

            rmat.RowNames = rowNames;
            Matrix QofU = Matrix.CreateIdentity(row);

            QofU.ColNames = rowNames;
            QofU.RowNames = rowNames;

            var equa = new MatrixEquation(mat, rmat)
            {
                Name = name, QofU = QofU
            };

            DataBind(equa);
        }
        private void DataBind(MatrixEquation mat)
        {
            Entity = mat;

            this.richTextBoxControl_left.Text = Entity.LeftSide.ToReadableText();
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(Entity.RightSide.ToReadableText());

            if (Entity.HasWeightOfRightSide && Entity.QofU.RowCount < 100)
            {
                sb.AppendLine("右边权逆阵");
                sb.AppendLine(Entity.QofU.ToReadableText());
            }

            this.richTextBoxControl_right.Text = sb.ToString();

            var path = Path.Combine(OutputDirectory, "Combied" + Setting.TextMatrixEquationFileExtension);

            WriteToTextFile(path);
            Geo.Utils.FormUtil.ShowOkAndOpenDirectory(Path.GetDirectoryName(path));
        }
Beispiel #15
0
        public void DataBind(MatrixEquation mat)
        {
            Entity = (mat);

            //具有固定参数,则生成打开
            if (this.HasOrEnableFixedParam)
            {
                var fixedStorage = this.GetFixedParamStorage();
                if (fixedStorage != null)
                {
                    ParamFixedMatrixEquationBuilder equationBuilder = new ParamFixedMatrixEquationBuilder(fixedStorage);
                    var newEq = equationBuilder.Build(Entity);

                    MatrixEquationForm form = new MatrixEquationForm();
                    form.DataBind(newEq);
                    form.Show();
                }
            }

            StringBuilder sb = new StringBuilder();

            if (Entity.MaxSize > MaxOrderToShow)
            {
                sb.Append("超出最大显示阶数:" + Entity.MaxSize);
            }
            else
            {
                //左右方程
                this.richTextBoxControl_left.Text  = Entity.LeftSide.ToReadableText();
                this.richTextBoxControl_right.Text = Entity.RightSide.ToReadableText();

                if (Entity.HasWeightOfRightSide)
                {
                    richTextBoxControl_weightOfU.Text = Entity.QofU.ToReadableText();
                }

                sb.AppendLine("方程文本");
                sb.AppendLine(Entity.ToReadableText());
            }

            //法方程与观测残差
            var normal = Entity.NormalEquation;

            sb.AppendLine("法方程文本");
            sb.AppendLine(normal.ToReadableText());

            sb.AppendLine("参数计算结果");
            var est = normal.GetEstimated();

            sb.AppendLine(est.ToReadableText());

            var table = est.GetObjectTable();

            this.objectTableControl_result.DataBind(table);
            //写结果
            var paramPath = Path.Combine(OutputDirectory, "EstimatedParamOf" + Entity.Name + Setting.ParamFileExtension);

            ObjectTableWriter.Write(table, paramPath);


            sb.AppendLine("观测残差");
            sb.AppendLine(normal.GetResidual().ToReadableText());


            this.richTextBoxControl_result.Text = sb.ToString();
        }
Beispiel #16
0
        /// <summary>
        /// 用MatrixEquation得到的预测值
        /// </summary>
        /// <param name="str">实验号</param>
        /// <returns>预测值</returns>
        public static List <DataValue> getAllPredictValue(String str)
        {
            List <DataValue> lists = new List <DataValue>();
            List <DateTime>  dateTime;
            List <double>    a;
            List <string>    inTemp;
            List <double>    grainTemp;

            try
            {
                dateTime  = SqlData.sqlDataDate("dbo.小麦害虫种群变化数据表", "Date", str);
                a         = SqlData.sqlGetData("dbo.小麦害虫种群变化数据表", "CanShuValue", str);
                inTemp    = SqlData.sqlDataInTemp("dbo.小麦害虫种群变化数据表", "InTemp", str);
                grainTemp = SqlData.sqlDataGrainTemp("dbo.小麦害虫种群变化数据表", "GrainTemp", str);
            }
            catch (Exception e)
            {
                throw e;
            }

            string[]      strTemp = inTemp.ToArray();
            double[]      douTemp = grainTemp.ToArray();
            double[]      col0    = a.ToArray();
            DateTime[]    date    = dateTime.ToArray();
            List <double> dayDou  = new List <double>();//将有数据的日期转换为double类型

            for (int i = 0; i < date.Length; i++)
            {
                dayDou.Add(date[i].ToOADate());
            }

            List <double> doubleDay = new List <double>();

            for (double j = dayDou[0]; j <= dayDou[dayDou.Count - 1]; j++)
            {
                doubleDay.Add(j);
            }
            double[] ceshi = spline.setSplineData(dayDou.ToArray(), col0, doubleDay.ToArray());//实际值

            MatrixEquation mart = new MatrixEquation();

            double[] ceshi2 = mart.MultiLine(dayDou.ToArray(), col0, col0.Length, 3);
            int      index  = -1;
            DateTime dDay   = date[0];

            for (int i = 0; i < doubleDay.Count; i++)
            {
                DataValue datapoint = new DataValue();
                double    y1        = ceshi2[0] + ceshi2[1] * doubleDay[i] + ceshi2[2] * doubleDay[i] * doubleDay[i] + ceshi2[3] * doubleDay[i] * doubleDay[i] * doubleDay[i];
                datapoint.PredictData = y1;

                if (i % 7 == 0)
                {
                    index++;
                }
                datapoint.InTemp    = strTemp[index];
                datapoint.GrainTemp = douTemp[index];
                datapoint.date      = dDay.AddDays(1);
                dDay = datapoint.date;

                datapoint.ChaValue = ceshi[i] - y1;
                if (str == "000051")
                {
                    datapoint.Y = ceshi[i];
                }
                else if (str == "000052")
                {
                    datapoint.Y = ceshi[i];
                }
                else if (str == "000053")
                {
                    datapoint.Y = ceshi[i];
                }
                else if (str == "000054")
                {
                    datapoint.Y = ceshi[i];
                }
                lists.Add(datapoint);
            }
            return(lists);
        }
Beispiel #17
0
        /// <summary>
        /// 具有约束条件的参数平差的无限权解法解算模糊度固定。
        /// </summary>
        /// <param name="totalFloat"></param>
        /// <param name="fixedAmbiguities"></param>
        /// <returns></returns>
        public WeightedVector GetResultByWeighedParamAdjust(WeightedVector totalFloat, WeightedVector fixedAmbiguities)
        {
            if (fixedAmbiguities.Count == 0)
            {
                return(totalFloat);
            }

            int totalParamCount = totalFloat.Count; //待估参数个数
            int fixedAmbiCount  = fixedAmbiguities.Count;

            //平差系数阵
            var PA = new Matrix(totalFloat.Weights);
            var LA = new Matrix((IVector)totalFloat, true)
            {
                RowNames = totalFloat.ParamNames
            };
            var A  = DiagonalMatrix.GetIdentity(totalParamCount);//A x = l
            var LB = new Matrix((IVector)fixedAmbiguities, true)
            {
                RowNames = fixedAmbiguities.ParamNames
            };
            var PB = new Matrix(fixedAmbiguities.Weights);

            Matrix B = BuildCoeefOfFixedToFloat(totalFloat, fixedAmbiguities);

            var BTBP = B.Trans * PB;

            //A 为单位阵,不需要计算
            var NA = PA;      //AT * P * A
            var UA = PA * LA; //AT * P * L

            UA.ColNames = new List <string>()
            {
                "Names"
            };
            NA.ColNames = totalFloat.ParamNames;
            UA.RowNames = totalFloat.ParamNames;
            NA.RowNames = totalFloat.ParamNames;


            var NB = BTBP * B;
            var UB = BTBP * LB;

            UB.ColNames = new List <string>()
            {
                "Names"
            };
            NB.ColNames = totalFloat.ParamNames;
            UB.RowNames = totalFloat.ParamNames;
            NB.RowNames = totalFloat.ParamNames;

            MatrixEquation neA = new MatrixEquation(NA, UA);
            MatrixEquation neB = new MatrixEquation(NB, UB);
            var            eq  = neA + neB;

            var result = eq.GetEstimated();

            //整体矩阵验证, 2018.10.20, czs, in hmx, 已经验证与整体平差一致,但是如果权太大如1e40,则可能出现舍入误差,而失真!!
            if (false)
            {
                Matrix AB = new Matrix(A.RowCount + B.RowCount, A.ColCount);
                AB.SetSub(A);
                AB.SetSub(B, A.ColCount);

                Matrix PAB = new Matrix(PA.RowCount + PB.RowCount);
                PAB.SetSub(PA);
                PAB.SetSub(PB, PA.RowCount, PA.ColCount);

                Vector LAB = new Vector(totalFloat);
                LAB.AddRange(fixedAmbiguities);

                ParamAdjuster paramAdjuster = new ParamAdjuster();
                var           result2       = paramAdjuster.Run(new AdjustObsMatrix(new WeightedVector(LAB, PAB.Inversion), AB));
            }
            return(result);
        }
        private void DataBind(MatrixEquation mat)
        {
            Entity = mat;



            //具有固定参数,则生成打开
            if (this.HasOrEnableFixedParam)
            {
                var fixedStorage = this.GetFixedParamStorage();
                if (fixedStorage != null)
                {
                    ParamFixedMatrixEquationBuilder equationBuilder = new ParamFixedMatrixEquationBuilder(fixedStorage);
                    var newEq = equationBuilder.Build(Entity);

                    MatrixEquationForm form = new MatrixEquationForm();
                    form.DataBind(newEq);
                    form.Show();
                }
            }



            this.richTextBoxControl_left.Text = Entity.LeftSide.ToReadableText();
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(Entity.RightSide.ToReadableText());

            if (Entity.HasWeightOfRightSide && Entity.QofU.RowCount < 100)
            {
                sb.AppendLine("右边权逆阵");
                sb.AppendLine(Entity.QofU.ToReadableText());
            }

            this.richTextBoxControl_right.Text = sb.ToString();

            //输出
            var path = Path.Combine(OutputDirectory, mat.Name + Setting.TextMatrixEquationFileExtension);

            WriteToTextFile(path);


            //法方程与观测残差
            sb = new StringBuilder();
            var normal = Entity.NormalEquation;

            sb.AppendLine("法方程文本");
            sb.AppendLine(normal.ToReadableText());

            sb.AppendLine("参数计算结果");
            var est = normal.GetEstimated();

            sb.AppendLine(est.ToReadableText());

            var table = est.GetObjectTable();

            this.objectTableControl1.DataBind(table);
            //写结果
            var paramPath = Path.Combine(OutputDirectory, "EstimatedParamOf" + Entity.Name + Setting.ParamFileExtension);

            ObjectTableWriter.Write(table, paramPath);


            sb.AppendLine("观测残差");
            sb.AppendLine(normal.GetResidual().ToReadableText());

            richTextBoxControl_normal.Text = sb.ToString();
        }
Beispiel #19
0
        /// <summary>
        /// 构建不变参数的计算结果。
        /// 注意:需要控制参数的增减问题。
        /// 基本思路:增加则插入,减少则删除,通过参数名称来控制。
        /// </summary>
        /// <param name="obsMatrix"></param>
        /// <param name="NormalEquationSuperposer"></param>
        /// <returns></returns>
        public static AdjustResultMatrix GetConstParamResult(AdjustObsMatrix obsMatrix, NormalEquationSuperposer NormalEquationSuperposer)
        {
            //观测值权阵设置,对已知量赋值
            Matrix L               = new Matrix((IMatrix)obsMatrix.Observation);
            Matrix QL              = new Matrix(obsMatrix.Observation.InverseWeight);
            Matrix PL              = new Matrix(QL.GetInverse());
            Matrix A               = new Matrix(obsMatrix.Coefficient);
            Matrix AT              = A.Trans;
            Matrix B               = new Matrix(obsMatrix.SecondCoefficient);
            Matrix BT              = B.Trans;
            Matrix X0              = obsMatrix.HasApprox ? new Matrix(obsMatrix.ApproxVector, true) : null;
            Matrix Y0              = obsMatrix.HasSecondApprox ? new Matrix(obsMatrix.SecondApproxVector, true) : null;
            Matrix D               = obsMatrix.HasFreeVector ? new Matrix(obsMatrix.FreeVector, true) : null;
            int    obsCount        = L.RowCount;
            int    fixedParamCount = obsMatrix.SecondParamNames.Count;// B.ColCount;
            int    freedom         = obsCount - fixedParamCount;

            //观测值更新
            Matrix lxy = L - (A * X0 + B * Y0 + D); //采用估值计算的观测值小量

            Matrix ATPL = AT * PL;
            //法方程
            Matrix Na      = ATPL * A;
            Matrix Nab     = AT * PL * B;
            Matrix InverNa = Na.Inversion;
            Matrix J       = A * InverNa * AT * PL;
            Matrix I       = Matrix.CreateIdentity(J.RowCount);
            Matrix B2      = (I - J) * B; //新的系数阵 Ac, 原文中为 B波浪~
            Matrix B2T     = B2.Trans;
            Matrix B2TPL   = B2T * PL;
            Matrix NofB2   = B2TPL * B2;
            Matrix UofB2   = B2TPL * lxy;

            NofB2.ColNames = obsMatrix.SecondParamNames;
            NofB2.RowNames = obsMatrix.SecondParamNames;

            UofB2.RowNames = obsMatrix.SecondParamNames;
            UofB2.ColNames = new List <string>()
            {
                "ConstParam"
            };

            //生成法方程
            var ne = new MatrixEquation(NofB2, UofB2);

            //叠加法方程
            NormalEquationSuperposer.Add(ne);//添加到法方程迭加器中

            var acNe = NormalEquationSuperposer.CurrentAccumulated;

            Matrix inverN = acNe.N.Inversion;
            Matrix y      = inverN * acNe.U;

            y.RowNames = acNe.ParamNames;
            Matrix Qy = inverN;

            Qy.ColNames = acNe.ParamNames;
            Qy.RowNames = acNe.ParamNames;
            var estY = new WeightedVector(y, Qy)
            {
                ParamNames = acNe.ParamNames
            };

            var    V    = B2 * y - lxy;
            Matrix Qv   = QL - B2 * Qy * B2T;
            Matrix Y    = Y0 + y;
            var    vtpv = (V.Trans * PL * V).FirstValue;
            double s0   = vtpv / (freedom == 0 ? 0.1 : freedom);//单位权方差

            WeightedVector CorrectedEstimate = new WeightedVector(Y, Qy);

            WeightedVector estV = new WeightedVector(V, Qv)
            {
                ParamNames = obsMatrix.Observation.ParamNames
            };
            Matrix Lhat         = L + V;
            Matrix QLhat        = B2 * Qy * B2T;
            var    correctedObs = new WeightedVector(Lhat, QLhat)
            {
                ParamNames = obsMatrix.Observation.ParamNames
            };

            AdjustResultMatrix result = new AdjustResultMatrix()
                                        .SetAdjustmentType(AdjustmentType.递归最小二乘)
                                        .SetEstimated(estY)
                                        .SetCorrection(estV)
                                        .SetCorrectedObs(correctedObs)
                                        .SetCorrectedEstimate(CorrectedEstimate)
                                        .SetObsMatrix(obsMatrix)
                                        .SetFreedom(freedom)
                                        .SetVarianceFactor(s0)
                                        .SetVtpv(vtpv);

            return(result);
        }
Beispiel #20
0
        /// <summary>
        /// 参数平差的矩阵方程
        /// </summary>
        /// <returns></returns>
        public MatrixEquation GetObsMatrixEquation(string name)
        {
            MatrixEquation eq = new MatrixEquation(this.Coefficient, this.Observation, name);

            return(eq);
        }