/// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int row = ObsCount;

            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(ObsCount);

            double invFactorOfRange = 1;
            double invFactorOfPhase = Option.PhaseCovaProportionToRange;
            int    epochIndex       = 0;

            foreach (var epoch in this.CurrentMaterial)
            {
                int satIndex        = 0;
                int epochStartIndex = this.EnabledSatCount * 2 * epochIndex;//当前历元参数起始编号
                foreach (var prn in EnabledPrns)
                {
                    int rangIndex  = GetRangIndex(satIndex, epochStartIndex);
                    int phaseIndex = GetPhaseIndex(satIndex, epochStartIndex);

                    EpochSatellite e = epoch[prn];

                    double inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                    inverseWeight[rangIndex][rangIndex]   = inverseWeightOfSat * invFactorOfRange;
                    inverseWeight[phaseIndex][phaseIndex] = inverseWeightOfSat * invFactorOfPhase;

                    satIndex++;
                }
                epochIndex++;
            }

            return(new Matrix(inverseWeight));
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <param name="factor">载波和伪距权逆阵因子(模糊度固定后,才采用默认值!)</param>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int satCount = EnabledSatCount;// EpochInfo.EnabledSatCount;
            int row      = satCount * 2;
            // double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(row);
            DiagonalMatrix inverseWeight = new DiagonalMatrix(row, 1);

            double [] inverseWeightVector = inverseWeight.Vector;
            double    invFactorOfRange    = 1;
            double    invFactorOfPhase    = Option.PhaseCovaProportionToRange;
            //   double invFactorOfPhase =  0.003 * 0.003;

            int i = 0;

            foreach (var prn in CurrentMaterial.EnabledPrns)// 一颗卫星1行
            {
                EpochSatellite e = this.CurrentMaterial[prn];
                double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                //如果具有周跳,则权值同伪距 ???
                //if (e.HasCycleSlip)
                //    invFactorOfPhase = invFactorOfRange;

                //inverseWeight[time][time] =8.87 * inverseWeightOfSat * invFactorOfRange; //8.87是按误差传播定律算的组合值的方差
                //inverseWeight[time + satCount][time + satCount] = 8.87 *inverseWeightOfSat * invFactorOfPhase;
                inverseWeightVector[i]            = inverseWeightOfSat * invFactorOfRange;
                inverseWeightVector[i + satCount] = inverseWeightOfSat * invFactorOfPhase;

                i++;
            }
            return(inverseWeight);
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int satCount = CurrentMaterial.EnabledSatCount;
            int row      = satCount * 4;

            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(row);

            double invFactorOfRange = 1;
            double invFactorOfPhase = Option.PhaseCovaProportionToRange;

            int satIndex = 0;

            foreach (var sat in CurrentMaterial.EnabledSats)
            {
                double inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(sat);

                int rowIndexOfRangeA = satIndex;
                int rowIndexOfRangeB = satIndex + EnabledSatCount;
                int rowIndexOfPhaseA = satIndex + 2 * EnabledSatCount;
                int rowIndexOfPhaseB = satIndex + 3 * EnabledSatCount;

                inverseWeight[rowIndexOfRangeA][rowIndexOfRangeA] = inverseWeightOfSat * invFactorOfRange;
                inverseWeight[rowIndexOfRangeB][rowIndexOfRangeB] = inverseWeightOfSat * invFactorOfRange;

                inverseWeight[rowIndexOfPhaseA][rowIndexOfPhaseA] = inverseWeightOfSat * invFactorOfPhase;
                inverseWeight[rowIndexOfPhaseB][rowIndexOfPhaseB] = inverseWeightOfSat * invFactorOfPhase;

                satIndex++;
            }

            return(new ArrayMatrix(inverseWeight));
        }
Exemple #4
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            DiagonalMatrix inverseWeight = new DiagonalMatrix(1, 1);

            inverseWeight[0, 0] = SatWeightProvider.GetInverseWeightOfRange(this.CurrentMaterial);
            return(inverseWeight);
        }
Exemple #5
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            var inverseWeight = Matrix.CreateIdentity(this.CurrentMaterial.Count);
            int i             = 0;

            foreach (var item in this.CurrentMaterial)
            {
                inverseWeight[i, i] = SatWeightProvider.GetInverseWeightOfRange(item);
                i++;
            }
            return(inverseWeight);
        }
Exemple #6
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs( )
        {
            int satCount = CurrentMaterial.EnabledSatCount;

            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(satCount);

            for (int i = 0; i < satCount; i++)
            {
                EpochSatellite e = this.CurrentMaterial[i];
                inverseWeight[i][i] = SatWeightProvider.GetInverseWeightOfRange(e);
            }
            return(new ArrayMatrix(inverseWeight));
        }
Exemple #7
0
        private void InverseWeightOfEpoch(double[] inverseWeightVector, double invFactorOfRange, double invFactorOfPhase, EpochInformation epoch)
        {
            foreach (var prn in epoch.EnabledPrns)
            {
                EpochSatellite e = epoch[prn];
                var            SiteSatAmbiguityName        = this.GnssParamNameBuilder.GetSiteSatAmbiguityParamName(e);
                int            IndexOfSiteSatAmbiguityName = ParamNames.IndexOf(SiteSatAmbiguityName);

                int row  = IndexOfSiteSatAmbiguityName - BaseCount;//行的索引号
                int next = row + ObsCount;

                double inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                inverseWeightVector[row]  = inverseWeightOfSat * invFactorOfRange;
                inverseWeightVector[next] = inverseWeightOfSat * invFactorOfPhase;
            }
        }
Exemple #8
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int row = CurrentMaterial.EnabledSatCount;

            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(row);

            double invFactorOfRange = 1;

            for (int i = 0; i < row; i++)
            {
                EpochSatellite e = this.CurrentMaterial[i];
                double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                inverseWeight[i][i] = inverseWeightOfSat * invFactorOfRange;
            }
            return(new Matrix(inverseWeight));
        }
Exemple #9
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <param name="factor">载波和伪距权逆阵因子(模糊度固定后,才采用默认值!)</param>
        /// <returns></returns>
        public IMatrix BulidInverseWeightOfObs()
        {
            //double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(ObsCount * 2);
            DiagonalMatrix inverseWeight = new DiagonalMatrix(ObsCount * 2);

            double[] inverseWeightVector = inverseWeight.Vector;
            double   invFactorOfRange    = 1;
            double   invFactorOfPhase    = Option.PhaseCovaProportionToRange;

            int index1 = 0;

            foreach (var epoch in this.CurrentMaterial)
            {
                foreach (var prn in epoch.EnabledPrns)
                {
                    EpochSatellite e = epoch[prn];
                    double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                    inverseWeight[index1]            = inverseWeightOfSat * invFactorOfRange;
                    inverseWeight[index1 + ObsCount] = inverseWeightOfSat * invFactorOfPhase;
                    index1++;
                }
            }

            //start = DateTime.Now;
            //int index = 0;
            //foreach (var epoch in this.CurrentMaterial)
            //{
            //    foreach (var prn in epoch.EnabledPrns)
            //    {
            //        EpochSatellite e = epoch[prn];
            //        double inverseWeightOfSat = SatWeightProvider.GetInverseWeight(e);
            //        //inverseWeight[index][index] = inverseWeightOfSat * invFactorOfRange;
            //        //inverseWeight[index + ObsCount][index + ObsCount] = inverseWeightOfSat * invFactorOfPhase;
            //        inverseWeight[index, index] = inverseWeightOfSat * invFactorOfRange;
            //        inverseWeight[index + ObsCount, index + ObsCount] = inverseWeightOfSat * invFactorOfPhase;
            //        index++;
            //    }
            //}
            //span = DateTime.Now - start;
            //Console.WriteLine(span.TotalMilliseconds + "ms计算Q-");


            //var ss = inverseWeight - inverseWeight1;
            return(inverseWeight);
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(EnabledSatCount);
            bool       hasEstCoord   = !XYZ.IsZeroOrEmpty(CurrentMaterial.SiteInfo.ApproxXyz);
            int        i             = 0;

            foreach (var sat in CurrentMaterial.EnabledSats)// 一颗卫星1行
            {
                double inverseWeightOfSat = 1;
                if (hasEstCoord)//高度角有关,如果测站坐标为 0,则高度角计算错误。
                {
                    inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(sat);
                }

                inverseWeight[i][i] = inverseWeightOfSat + (sat.StdDevOfRange * sat.StdDevOfRange);

                i++;
            }
            return(new Matrix(inverseWeight));
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <returns></returns>
        protected virtual IMatrix BulidInverseWeightOfObs()
        {
            int            satCount      = EnabledSatCount;
            int            row           = satCount * 2;
            DiagonalMatrix inverseWeight = new DiagonalMatrix(row, 1);

            double[] inverseWeightVector = inverseWeight.Vector;
            double   invFactorOfRange    = 1;
            double   invFactorOfPhase    = this.PhaseCovaProportionToRange;//  0.003 * 0.003;
            int      i = 0;

            foreach (var sat in CurrentMaterial.EnabledSats)// 一颗卫星1行
            {
                double inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(sat);
                inverseWeightVector[i]            = inverseWeightOfSat * invFactorOfRange;
                inverseWeightVector[i + satCount] = inverseWeightOfSat * invFactorOfPhase;
                i++;
            }
            return(inverseWeight);
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <param name="factor">载波和伪距权逆阵因子(模糊度固定后,才采用默认值!)</param>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            // factor = 1.0e-4;//5.0e-5;1.0e-4//   //1 / 140 / 140; 5.1020408163265306122448979591837e-5

            int satCount = CurrentMaterial.EnabledSatCount;

            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(this.ObsCount);

            double invFactorOfRange = 1;
            double invFactorOfPhase = Option.PhaseCovaProportionToRange;

            for (int i = 0; i < satCount; i++)
            {
                EpochSatellite e = this.CurrentMaterial[i];
                double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                inverseWeight[i][i] = inverseWeightOfSat * invFactorOfRange;
                inverseWeight[i + satCount][i + satCount] = inverseWeightOfSat * invFactorOfPhase;
            }
            return(new ArrayMatrix(inverseWeight));
        }
Exemple #13
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <param name="factor">载波和伪距权逆阵因子(模糊度固定后,才采用默认值!)</param>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            DiagonalMatrix inverseWeight    = new DiagonalMatrix(ObsCount * 2);
            double         invFactorOfRange = 1;
            double         invFactorOfPhase = Option.PhaseCovaProportionToRange;
            int            index            = 0;

            foreach (var epoch in this.CurrentMaterial)
            {
                foreach (var prn in epoch.EnabledPrns)
                {
                    EpochSatellite e = epoch[prn];
                    double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                    inverseWeight[index, index] = inverseWeightOfSat * invFactorOfRange;
                    inverseWeight[index + ObsCount, index + ObsCount] = inverseWeightOfSat * invFactorOfPhase;
                    index++;
                }
            }

            return(inverseWeight);
        }
Exemple #14
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int row = ObsCount;

            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(ObsCount);

            double invFactorOfRange = 1;
            int    index            = 0;

            foreach (var epoch in this.CurrentMaterial)
            {
                foreach (var prn in EnabledPrns)
                {
                    EpochSatellite e = epoch[prn];
                    double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                    inverseWeight[index][index] = inverseWeightOfSat * invFactorOfRange;
                    index++;
                }
            }

            return(new Matrix(inverseWeight));
        }
        /// <summary>
        /// 1. 处理一颗卫星的宽项值,包含和基准卫星的差分值。
        /// </summary>
        /// <param name="tableRow"></param>
        /// <param name="sat"></param>
        private void SolveAndUpdateWideLane(EpochSatellite sat)
        {
            var prn       = sat.Prn;
            var prnKey    = prn.ToString();
            var smoothKey = BuildWideLaneKey(prnKey);

            var mwCycle = sat.Combinations.MwPhaseCombinationValue; // MW 值
            var filter  = this.WideLaneFilterManager.GetOrCreate(prnKey);

            filter.Buffers = GetMwValues(prn);
            var rms           = IsSetWeightWithSat ?  SatWeightProvider.GetStdDev(sat) : 1;
            var input         = new RmsedNumeral(mwCycle, rms);
            var smoothAligned = filter.Filter(input);

            LatestEpochSatWmValues[sat.Prn] = new EpochSatDifferValue()
            {
                Index       = sat.EpochInfo.EpochIndexOfDay,
                Prn         = sat.Prn,
                RawValue    = mwCycle - filter.IntegerPart,
                SmoothValue = smoothAligned.Value
            };
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(EnabledSatCount);

            double invFactorOfRange = 10;//URE

            int i = 0;

            foreach (var prn in CurrentMaterial.EnabledPrns)// 一颗卫星1行
            {
                EpochSatellite e = this.CurrentMaterial[prn];
                double         inverseWeightOfSat = 1;
                if (e.SiteInfo.ApproxXyz.IsZero)//高度角有关,如果测站坐标为 0,则高度角计算错误。
                {
                    inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                }

                inverseWeight[i][i] = inverseWeightOfSat * invFactorOfRange;

                i++;
            }
            return(new Matrix(inverseWeight));
        }
Exemple #17
0
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <param name="factor">载波和伪距权逆阵因子(模糊度固定后,才采用默认值!)</param>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int            satCount      = EnabledSatCount;
            int            row           = satCount * 2;
            DiagonalMatrix inverseWeight = new DiagonalMatrix(row);

            double invFactorOfRange = 1;
            double invFactorOfPhase = Option.PhaseCovaProportionToRange;

            int i = 0;

            foreach (var prn in CurrentMaterial.EnabledPrns)// 一颗卫星1行
            {
                EpochSatellite e = this.CurrentMaterial[prn];
                double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                inverseWeight[i, i] = inverseWeightOfSat * invFactorOfRange;
                inverseWeight[i + satCount, i + satCount] = inverseWeightOfSat * invFactorOfPhase;

                i++;
            }
            return(inverseWeight);
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <returns></returns>
        public IMatrix BulidInverseWeightOfObs()
        {
            //double[][] inverseWeight = Geo.Utils.MatrixUtil.Create(ObsCount * 2);
            DiagonalMatrix inverseWeight = new DiagonalMatrix(ObsCount * 2);

            double[] inverseWeightVector = inverseWeight.Vector;
            double   invFactorOfRange    = 1;
            double   invFactorOfPhase    = Option.PhaseCovaProportionToRange;

            int index1 = 0;

            foreach (var epoch in this.CurrentMaterial)
            {
                foreach (var prn in epoch.EnabledPrns)
                {
                    EpochSatellite e = epoch[prn];
                    double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                    inverseWeight[index1]            = inverseWeightOfSat * invFactorOfRange;
                    inverseWeight[index1 + ObsCount] = inverseWeightOfSat * invFactorOfPhase;
                    index1++;
                }
            }
            return(inverseWeight);
        }
        /// <summary>
        /// 双频载波观测值的双差协方差矩阵
        /// </summary>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int satCount = EnabledSatCount;

            //首先,建立非差观测值的权逆阵,这里前一半是rov站的,后一半是ref站的.单频基础上扩展双频
            int            row              = (satCount) * 2;
            DiagonalMatrix inverseWeight    = new DiagonalMatrix(row);
            double         invFactorOfPhase = 1e-4;
            int            index            = 0;
            int            baseindex        = this.RovInfo.EnabledPrns.IndexOf(CurrentBasePrn);
            EpochSatellite baseRovEle       = this.RovInfo.EnabledSats[baseindex];
            EpochSatellite baseRefEle       = this.RefInfo.EnabledSats[baseindex];
            double         baseRovSat       = SatWeightProvider.GetInverseWeightOfRange(baseRovEle); //返回的伪距的方差
            double         baseRefSat       = SatWeightProvider.GetInverseWeightOfRange(baseRefEle); //返回的伪距的方差

            inverseWeight[index, index] = baseRovSat * invFactorOfPhase;
            inverseWeight[index + satCount, index + satCount] = baseRefSat * invFactorOfPhase;

            for (int i = 0; i < satCount; i++)
            {
                if (i != baseindex)
                {
                    index++;
                    EpochSatellite e = this.RovInfo.EnabledSats[i];
                    double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e); //返回的伪距的方差
                    inverseWeight[index, index] = inverseWeightOfSat * invFactorOfPhase;

                    e = this.RefInfo[i];
                    inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);
                    inverseWeight[index + satCount, index + satCount] = inverseWeightOfSat * invFactorOfPhase;
                }
            }
            DiagonalMatrix undiffInverseWeigth = (inverseWeight);

            //然后,建立单差的权逆阵
            double[][] sigleCoeff = Geo.Utils.MatrixUtil.Create(satCount, satCount * 2, 0f);
            for (int i = 0; i < satCount; i++)
            {
                sigleCoeff[i][i]            = 1;  //流动站
                sigleCoeff[i][satCount + i] = -1; //参考站
            }
            IMatrix sigleCoeffMatrix   = new ArrayMatrix(sigleCoeff);
            IMatrix sigleInverseWeigth = sigleCoeffMatrix.Multiply(undiffInverseWeigth).Multiply(sigleCoeffMatrix.Transposition);


            //最后,建立双差的权逆阵
            double[][] doubleCoeff = Geo.Utils.MatrixUtil.Create((satCount - 1), satCount, 0f);
            // int baseindex = this.RovInfo.EnabledPrns.IndexOf(CurrentBasePrn);
            int satIndex = 0;

            foreach (var item in RovInfo.EnabledSats)
            {
                if (item.Prn != CurrentBasePrn)
                {
                    doubleCoeff[satIndex][0] = -1;           //参考星
                    int index0 = this.RovInfo.EnabledPrns.IndexOf(item.Prn);
                    doubleCoeff[satIndex][satIndex + 1] = 1; //流动星
                    satIndex++;
                }
            }
            IMatrix doubleCoeffMatrix   = new ArrayMatrix(doubleCoeff);
            IMatrix doubleInverseWeigth = doubleCoeffMatrix.Multiply(sigleInverseWeigth).Multiply(doubleCoeffMatrix.Transposition);

            //发现了吗?上面构建的是单频载波双差的权逆阵,而双频的呢?
            //可以重新建立(适合认为每个频率不一样的观测噪声),或者是两个独立模块,组合在一个大矩阵里。下面用第二种方式。

            double[][] DDelements = Geo.Utils.MatrixUtil.Create((satCount - 1) * 2, (satCount - 1) * 2, 0f);
            for (int i = 0; i < (satCount - 1); i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    DDelements[i][j] = doubleInverseWeigth[i, j];
                    DDelements[i + (satCount - 1)][j + (satCount - 1)] = doubleInverseWeigth[i, j];
                }
            }
            for (int i = 0; i < (satCount - 1) * 2; i++)
            {
                for (int j = i; j < (satCount - 1) * 2; j++)
                {
                    DDelements[i][j] = DDelements[j][i];
                }
            }
            IMatrix DDInverseWeigth = new Matrix(DDelements);

            return(DDInverseWeigth);
        }
        /// <summary>
        /// 遍历每一个历元
        /// </summary>
        /// <param name="epochInfo"></param>
        /// <returns></returns>
        public override bool Revise(ref EpochInformation epochInfo)
        {
            //如果没有基准卫星,则不可计算
            if (!epochInfo.EnabledPrns.Contains(BasePrn))
            {
                return(false);
            }

            //1.计算宽项滤波值,并存储
            foreach (var sat in epochInfo)
            {
                SolveAndUpdateWideLane(sat);
            }

            //2.计算平滑宽项星间差分值
            var baseMwValue = this.LatestEpochSatWmValues[BasePrn];

            foreach (var sat in epochInfo) //只处理本历元具有的卫星
            {
                var val = this.LatestEpochSatWmValues[sat.Prn];
                //计算差分值
                SovleAndUpdateDifferValue(val, baseMwValue);
            }

            //3.提取PPP计算结果,模糊度差分结果,先不做平滑
            foreach (var prn in epochInfo.EnabledPrns)
            {
                var floatVal = PppResult.GetFloatAmbiguityCycle(prn);
                LatestEpochFloatAmbiguityValues[prn] = new EpochSatDifferValue()
                {
                    Index       = epochInfo.EpochIndexOfDay,
                    Prn         = prn,
                    RawValue    = floatVal,
                    SmoothValue = floatVal,
                };
            }
            //3.1 星间单差值,更新到结果
            var baseFloat = this.LatestEpochFloatAmbiguityValues[BasePrn];

            foreach (var prn in epochInfo.EnabledPrns)
            {
                var val = LatestEpochFloatAmbiguityValues[prn];
                val.DifferValue = val.SmoothValue - baseFloat.SmoothValue;
            }

            //4.计算窄巷值
            foreach (var sat in epochInfo.EnabledSats)
            {
                var prn      = sat.Prn;
                var prnKey   = prn.ToString();
                var val      = LatestEpochFloatAmbiguityValues[prn];
                var wideLane = this.LatestEpochSatWmValues[sat.Prn];

                double fcbOfWideLaneDiffer = 0;
                var    differkey           = BuildDifferKey(prn);
                if (DifferFcbManager != null && DifferFcbManager.Contains(differkey))
                {
                    var dcb = DifferFcbManager.Get(differkey).Last;
                    fcbOfWideLaneDiffer = dcb.WideLaneValue;
                    if (Math.Abs(dcb.Time - sat.ReceiverTime) > 7 * 3600 * 24)
                    {
                        log.Warn("提供的宽项星间单差已经超过一周!");
                    }
                }
                var intWideLane = wideLane.DifferValue - fcbOfWideLaneDiffer;            //此处应该减去星间单差的小数部分。2016.10.20.
                var wideLaneInt = (int)Math.Round(intWideLane);
                var narrowValue = GetNarrowLaneValue(sat, val.DifferValue, wideLaneInt); //此处应该固定模糊度,不应该直接取整。

                this.LatestEpochNarrowLaneValues[prn] = new EpochSatValue()
                {
                    Index    = epochInfo.EpochIndexOfDay,
                    Prn      = prn,
                    RawValue = narrowValue,
                    Tag      = wideLaneInt // 存储整型宽项模糊度
                };

                //获取小数部分
                var narrowBuffer = NarrowBufferManager.GetOrCreate(prnKey);
                if (narrowBuffer.IsFull)
                {
                    var filter = this.NarrowLaneFilterManager.GetOrCreate(prnKey);
                    filter.Buffers = narrowBuffer;
                    var rms           = IsSetWeightWithSat ? SatWeightProvider.GetStdDev(sat) : 1;
                    var input         = new RmsedNumeral(narrowValue, rms);
                    var smoothAligned = filter.Filter(input);
                    this.LatestEpochNarrowLaneValues[prn].SmoothValue = smoothAligned.Value;
                }

                narrowBuffer.Add(narrowValue);
            }

            //3.输出
            if (IsOutputDetails)
            {
                TableStorage.NewRow();
                TableStorage.AddItem("Epoch", epochInfo.ReceiverTime.ToShortTimeString());

                foreach (var sat in epochInfo.EnabledSats) //只处理本历元具有的卫星
                {
                    var val         = this.LatestEpochSatWmValues[sat.Prn];
                    var prnKey      = val.Prn.ToString();
                    var wideLaneKey = BuildWideLaneKey(prnKey);

                    //宽项
                    TableStorage.AddItem(wideLaneKey + "_Raw", val.RawValue);
                    TableStorage.AddItem(wideLaneKey + "_Smooth", val.SmoothValue);
                    TableStorage.AddItem(wideLaneKey + "_MwDiffer", val.DifferValue);

                    //浮点解
                    var floatVal  = this.LatestEpochFloatAmbiguityValues[sat.Prn];
                    var floatKey  = prnKey;
                    var differKey = BuildDifferKey(prnKey);

                    TableStorage.AddItem(floatKey + "_FloatAmbi_Raw", floatVal.RawValue);
                    //TableStorage.AddItem(floatKey + "_Smooth", floatVal.SmoothValue);
                    TableStorage.AddItem(differKey, floatVal.DifferValue);

                    //窄巷
                    var narrowVal     = this.LatestEpochNarrowLaneValues[sat.Prn];
                    var narrowLaneKey = BuildNarrowLaneKey(prnKey);
                    TableStorage.AddItem(narrowLaneKey + "_Raw", narrowVal.RawValue);
                    TableStorage.AddItem(narrowLaneKey + "_WideLaneInt", narrowVal.Tag);
                    TableStorage.AddItem(narrowLaneKey + "_Smooth", narrowVal.SmoothValue);
                    //TableStorage.AddItem(narrowLaneKey + "_MwDiffer", narrowVal.DifferValue);
                }
            }
            return(true);
        }
        /// <summary>
        /// 观测量的权逆阵,一个对角阵。按照先伪距,后载波的顺序排列。
        /// 标准差由常数确定,载波比伪距标准差通常是 1:100,其方差比是 1:10000.
        /// 1.0/140*140=5.10e-5
        /// </summary>
        /// <param name="factor">载波和伪距权逆阵因子(模糊度固定后,才采用默认值!)</param>
        /// <returns></returns>
        protected IMatrix BulidInverseWeightOfObs()
        {
            int satCount = EnabledSatCount;

            //首先建立非差观测值的权逆阵,这里前一半是rov站的,后一半是ref站的
            int            row           = (satCount) * 4;
            DiagonalMatrix inverseWeight = new DiagonalMatrix(row);

            double invFactorOfRange = 1;
            double invFactorOfPhase = Option.PhaseCovaProportionToRange;

            for (int i = 0; i < satCount; i++)
            {
                EpochSatellite e = this.RovInfo.EnabledSats[i];
                double         inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                inverseWeight[i, i] = inverseWeightOfSat * invFactorOfRange;
                inverseWeight[i + satCount, i + satCount] = inverseWeightOfSat * invFactorOfPhase;

                e = this.RefInfo[i];
                inverseWeightOfSat = SatWeightProvider.GetInverseWeightOfRange(e);

                inverseWeight[i + 2 * satCount, i + 2 * satCount] = inverseWeightOfSat * invFactorOfRange;
                inverseWeight[i + 3 * satCount, i + 3 * satCount] = inverseWeightOfSat * invFactorOfPhase;
            }

            DiagonalMatrix undiffInverseWeigth = (inverseWeight);

            double[][] sigleCoeff = Geo.Utils.MatrixUtil.Create(satCount * 2, satCount * 4, 0f);
            for (int i = 0; i < 2 * satCount; i++)
            {
                sigleCoeff[i][i] = 1;                 //流动站
                sigleCoeff[i][2 * satCount + i] = -1; //参考站
            }

            IMatrix sigleCoeffMatrix   = new ArrayMatrix(sigleCoeff);
            IMatrix sigleInverseWeigth = sigleCoeffMatrix.Multiply(undiffInverseWeigth).Multiply(sigleCoeffMatrix.Transposition);

            double[][] doubleCoeff = Geo.Utils.MatrixUtil.Create((satCount - 1) * 2, satCount * 2, 0f);
            int        baseindex   = this.RovInfo.EnabledPrns.IndexOf(CurrentBasePrn);
            int        satIndex    = 0;

            foreach (var item in RovInfo.EnabledSats)
            {
                if (item.Prn != CurrentBasePrn)
                {
                    doubleCoeff[satIndex][baseindex] = -1; //参考星
                    int index = this.RovInfo.EnabledPrns.IndexOf(item.Prn);
                    doubleCoeff[satIndex][index] = 1;      //流动星
                    //载波
                    doubleCoeff[satIndex + satCount - 1][baseindex + satCount] = -1;
                    doubleCoeff[satIndex + satCount - 1][index + satCount]     = 1;
                    satIndex++;
                }
            }

            IMatrix doubleCoeffMatrix   = new ArrayMatrix(doubleCoeff);
            IMatrix doubleInverseWeigth = doubleCoeffMatrix.Multiply(sigleInverseWeigth).Multiply(doubleCoeffMatrix.Transposition);

            return(doubleInverseWeigth);
        }