private static JamaMatrix PseudoInverseBySVD(JamaMatrix gm)
        {
            if (gm.RowDimension < gm.ColumnDimension)
            {
                JamaMatrix gm2        = gm.transpose();
                JamaMatrix jamaMatrix = PolynomialImageTransformer.PseudoInverseBySVD(gm2);
                return(jamaMatrix.transpose());
            }
            if (gm.RowDimension == gm.ColumnDimension)
            {
                return(gm.inverse());
            }
            SingularValueDecomposition singularValueDecomposition = new SingularValueDecomposition(gm);
            JamaMatrix jamaMatrix2 = singularValueDecomposition.S.transpose();

            for (int i = 0; i < jamaMatrix2.RowDimension; i++)
            {
                double element = jamaMatrix2.GetElement(i, i);
                if (element != 0.0)
                {
                    jamaMatrix2.SetElement(i, i, 1.0 / element);
                }
            }
            return(singularValueDecomposition.getV().times(jamaMatrix2).times(singularValueDecomposition.getU().transpose()));
        }
        public PolynomialImageTransformer(RegistrationDefinition registration, InterpolationMode interpolationMode, int polynomialDegree) : base(registration, interpolationMode)
        {
            List <PositionAssociation> associationList = registration.GetAssociationList();
            TransformationStyle        arg_15_0        = registration.warpStyle;
            int num = associationList.Count;

            if (num == 2)
            {
                num++;
            }
            JamaMatrix jamaMatrix  = new JamaMatrix(num, 2);
            JamaMatrix jamaMatrix2 = new JamaMatrix(num, 2);

            for (int i = 0; i < num; i++)
            {
                LatLon latLon = (i == associationList.Count) ? PolynomialImageTransformer.getThirdPosition(associationList[0].sourcePosition.pinPosition.latlon, associationList[1].sourcePosition.pinPosition.latlon, true) : associationList[i].sourcePosition.pinPosition.latlon;
                jamaMatrix.SetElement(i, 0, latLon.lon);
                jamaMatrix.SetElement(i, 1, latLon.lat);
                LatLon latLon2 = (i == associationList.Count) ? PolynomialImageTransformer.getThirdPosition(MercatorCoordinateSystem.LatLonToMercator(associationList[0].globalPosition.pinPosition.latlon), MercatorCoordinateSystem.LatLonToMercator(associationList[1].globalPosition.pinPosition.latlon), false) : MercatorCoordinateSystem.LatLonToMercator(associationList[i].globalPosition.pinPosition.latlon);
                jamaMatrix2.SetElement(i, 0, latLon2.lon);
                jamaMatrix2.SetElement(i, 1, latLon2.lat);
            }
            this.destMercatorToSourceTransformer             = PolynomialImageTransformer.getPolyPointTransformer(jamaMatrix, jamaMatrix2, polynomialDegree);
            this.sourceToDestMercatorTransformer_approximate = PolynomialImageTransformer.getApproximateInverterPolyPointTransformer(jamaMatrix, jamaMatrix2, polynomialDegree);
            DownhillInverterPointTransformer flakyPointTransformer = new DownhillInverterPointTransformer(this.destMercatorToSourceTransformer, this.sourceToDestMercatorTransformer_approximate);
            IPointTransformer sourceToMercator = new RobustPointTransformer(flakyPointTransformer, this.sourceToDestMercatorTransformer_approximate);

            this.destLatLonToSourceTransformer = new LatLonToSourceTransform(this.destMercatorToSourceTransformer);
            this.sourceToDestLatLonTransformer = new SourceToLatLonTransform(sourceToMercator);
        }
        internal override void doTransformImage(GDIBigLockedImage sourceImage, MapRectangle sourceBounds, GDIBigLockedImage destImage, MapRectangle destBounds)
        {
            MapRectangle inr     = new MapRectangle(-0.5, -0.5, (double)destImage.Height - 0.5, (double)destImage.Width - 0.5);
            MapRectangle outr    = MapRectangle.MapRectangleIgnoreOrder(MercatorCoordinateSystem.LatLonToMercator(destBounds.GetNW()), MercatorCoordinateSystem.LatLonToMercator(destBounds.GetSE()));
            JamaMatrix   matrix  = PolynomialImageTransformer.FindAffineMatrix(inr, outr);
            MapRectangle outr2   = new MapRectangle(-0.5, -0.5, (double)sourceImage.Height - 0.5, (double)sourceImage.Width - 0.5);
            JamaMatrix   matrix2 = PolynomialImageTransformer.FindAffineMatrix(sourceBounds, outr2);

            FastImageWarper.doWarp(destImage, sourceImage, new IPointTransformer[]
            {
                new Affine2DPointTransformer(matrix),
                this.destMercatorToSourceTransformer,
                new Affine2DPointTransformer(matrix2)
            }, this.interpolationMode);
        }
        private static IPolyPointTransformer getPolyPointTransformer(JamaMatrix sourcePoints, JamaMatrix destPoints, int polynomialDegree)
        {
            JamaMatrix am     = IPolyPointTransformer.Polynomialize(destPoints, polynomialDegree);
            JamaMatrix matrix = PolynomialImageTransformer.SVDSolveApply(am, PolynomialImageTransformer.PointUnroll(sourcePoints));

            switch (polynomialDegree)
            {
            case 1:
                return(new FastPoly1PointTransformer(matrix));

            case 2:
                return(new FastPoly2PointTransformer(matrix));

            default:
                return(new SlowGeneralPolyPointTransformer(polynomialDegree, matrix));
            }
        }
        public static void TestFunc()
        {
            double[][] array    = new double[4][];
            double[][] arg_15_0 = array;
            int        arg_15_1 = 0;

            double[] array2 = new double[2];
            arg_15_0[arg_15_1] = array2;
            array[1]           = new double[]
            {
                1.02,
                0.93
            };
            array[2] = new double[]
            {
                0.0,
                1.0
            };
            double[][] arg_73_0 = array;
            int        arg_73_1 = 3;

            double[] array3 = new double[2];
            array3[0]          = 1.0;
            arg_73_0[arg_73_1] = array3;
            double[][] a          = array;
            JamaMatrix jamaMatrix = new JamaMatrix(a);

            PolynomialImageTransformer.RegularUnitGrid(4);
            JamaMatrix jamaMatrix2 = (JamaMatrix)jamaMatrix.Clone();

            jamaMatrix2.SetElement(1, 0, 1.0);
            jamaMatrix2.SetElement(1, 1, 1.0);
            JamaMatrix jamaMatrix3 = IPolyPointTransformer.Polynomialize(jamaMatrix, 2);
            JamaMatrix jamaMatrix4 = PolynomialImageTransformer.SVDSolveApply(jamaMatrix3, PolynomialImageTransformer.PointUnroll(jamaMatrix2));

            D.Say(0, "polyTransform:\n" + jamaMatrix4.ToString());
            JamaMatrix unrolledVector = jamaMatrix3.times(jamaMatrix4);

            D.Say(0, "testSolution:\n" + PolynomialImageTransformer.PointRoll(unrolledVector, 2).ToString());
            PolynomialImageTransformer.getPolyPointTransformer(jamaMatrix, jamaMatrix2, 2);
            LatLon p = new LatLon(0.93, 1.02);

            D.Say(0, "Invert test:\n" + PolynomialImageTransformer.getApproximateInverterPolyPointTransformer(jamaMatrix, jamaMatrix2, 2).getTransformedPoint(p).ToString());
        }
 private static IPolyPointTransformer getApproximateInverterPolyPointTransformer(JamaMatrix sourcePoints, JamaMatrix destPoints, int polynomialDegree)
 {
     return(PolynomialImageTransformer.getPolyPointTransformer(destPoints, sourcePoints, polynomialDegree));
 }
 private static JamaMatrix SVDSolveApply(JamaMatrix am, JamaMatrix b)
 {
     return(PolynomialImageTransformer.PseudoInverseBySVD(am).times(b));
 }
        private static JamaMatrix FindAffineMatrix(MapRectangle inr, MapRectangle outr)
        {
            JamaMatrix gm = PolynomialImageTransformer.CornersToVectorMatrix(inr);

            return(PolynomialImageTransformer.CornersToVectorMatrix(outr).times(PolynomialImageTransformer.PseudoInverseBySVD(gm)));
        }