コード例 #1
0
        public void QRDecomposition()
        {
            GeneralMatrix A = new GeneralMatrix(columnwise, 4);

            QRDecomposition QR = A.QRD();
            GeneralMatrix   R  = QR.R;

            Assert.IsTrue(GeneralTests.Check(A, QR.Q.Multiply(R)));
        }
コード例 #2
0
ファイル: SessionCollection.cs プロジェクト: gabbe/quickroute
        /// <summary>
        /// Using linear least squares algorithm described at http://en.wikipedia.org/wiki/Linear_least_squares
        /// </summary>
        /// <returns></returns>
        public Transformation CalculateAverageTransformation()
        {
            var averageProjectionOrigin = new LongLat();

            foreach (var session in this)
            {
                averageProjectionOrigin += session.ProjectionOrigin / Count;
            }

            if (Count == 0)
            {
                return(null);
            }
            var n   = 4;
            var XtX = new GeneralMatrix(n, n);
            var Xty = new GeneralMatrix(n, 1);
            var numberOfUnknowns = 0;

            foreach (var session in this)
            {
                var m = session.Handles.Length;
                if (m < 2)
                {
                    continue;
                }
                numberOfUnknowns += m;

                var startDistance = session.Route.GetAttributeFromParameterizedLocation(WaypointAttribute.Distance, session.Route.FirstPL).Value;
                for (var i = 0; i < m; i++)
                {
                    var longLat     = session.Route.GetLocationFromParameterizedLocation(session.Handles[i].ParameterizedLocation);
                    var p           = longLat.Project(averageProjectionOrigin); // projected point on earth (metres)
                    var q           = session.Handles[i].Location;              // point on map image (pixels)
                    var endDistance = (i != m - 1)
                              ? (session.Route.GetAttributeFromParameterizedLocation(WaypointAttribute.Distance, session.Handles[i].ParameterizedLocation).Value +
                                 session.Route.GetAttributeFromParameterizedLocation(WaypointAttribute.Distance, session.Handles[i + 1].ParameterizedLocation).Value) / 2
                              : session.Route.GetAttributeFromParameterizedLocation(WaypointAttribute.Distance, session.Route.LastPL).Value;
                    var w = endDistance - startDistance; // weight
                    startDistance = endDistance;

                    XtX.SetElement(0, 0, XtX.GetElement(0, 0) + w * (p.X * p.X + p.Y * p.Y));
                    XtX.SetElement(0, 2, XtX.GetElement(0, 2) + w * p.X);
                    XtX.SetElement(0, 3, XtX.GetElement(0, 3) - w * p.Y);
                    XtX.SetElement(1, 1, XtX.GetElement(1, 1) + w * (p.X * p.X + p.Y * p.Y));
                    XtX.SetElement(1, 2, XtX.GetElement(1, 2) + w * p.Y);
                    XtX.SetElement(1, 3, XtX.GetElement(1, 3) + w * p.X);
                    XtX.SetElement(2, 0, XtX.GetElement(2, 0) + w * p.X);
                    XtX.SetElement(2, 1, XtX.GetElement(2, 1) + w * p.Y);
                    XtX.SetElement(2, 2, XtX.GetElement(2, 2) + w);
                    XtX.SetElement(3, 0, XtX.GetElement(3, 0) - w * p.Y);
                    XtX.SetElement(3, 1, XtX.GetElement(3, 1) + w * p.X);
                    XtX.SetElement(3, 3, XtX.GetElement(3, 3) + w);

                    Xty.SetElement(0, 0, Xty.GetElement(0, 0) + w * (q.X * p.X - q.Y * p.Y));
                    Xty.SetElement(1, 0, Xty.GetElement(1, 0) + w * (q.X * p.Y + q.Y * p.X));
                    Xty.SetElement(2, 0, Xty.GetElement(2, 0) + w * q.X);
                    Xty.SetElement(3, 0, Xty.GetElement(3, 0) + w * q.Y);
                }
            }

            var T = new GeneralMatrix(3, 3);

            if (numberOfUnknowns == 0)
            {
                T = this[0].InitialTransformationMatrix;
            }
            else if (numberOfUnknowns == 1)
            {
                T = this[0].Handles[0].TransformationMatrix;
            }
            else
            {
                var B = XtX.QRD().Solve(Xty);

                T.SetElement(0, 0, B.GetElement(0, 0));
                T.SetElement(0, 1, B.GetElement(1, 0));
                T.SetElement(0, 2, B.GetElement(2, 0));
                T.SetElement(1, 0, B.GetElement(1, 0));
                T.SetElement(1, 1, -B.GetElement(0, 0));
                T.SetElement(1, 2, B.GetElement(3, 0));
                T.SetElement(2, 0, 0);
                T.SetElement(2, 1, 0);
                T.SetElement(2, 2, 1);
            }
            return(new Transformation(T, averageProjectionOrigin));
        }
コード例 #3
0
        /// <summary>
        /// QR�ֽⷨ
        /// </summary>
        /// <param name="st7"></param>
        public void CalculateTrans7Param3(List<Coords7ST> st7)
        {
            double[][] A = new double[0][];
            double[][] B = new double[0][];

            InitMatrixAB(ref A, ref B, st7);

            GeneralMatrix matrixA = new GeneralMatrix(A);
            GeneralMatrix matrixB = new GeneralMatrix(B);

            QRDecomposition qrDecp = matrixA.QRD();
            GeneralMatrix q = qrDecp.Q;
            GeneralMatrix r = qrDecp.R;

            GeneralMatrix matrixParam = r.Inverse().Multiply(q.Transpose()).Multiply(matrixB);

            this.Set4Param(matrixParam.GetElement(0, 0), matrixParam.GetElement(1, 0), matrixParam.GetElement(2, 0), matrixParam.GetElement(6, 0));
            this.SetRotationParam(matrixParam.GetElement(3, 0), matrixParam.GetElement(4, 0), matrixParam.GetElement(5, 0));
        }