Exemple #1
0
        /// <summary>
        /// Compute rigid motion using the singular value decomposition (SVD).
        /// Returns the best transformation that moves X towards Y minimizing the mean squared error (MSE),
        /// such that y = x*R + offset
        /// </summary>
        /// <param name="x">The list of source points (read-only)</param>
        /// <param name="y">The list of destination points (read-only)</param>
        /// <param name="R">The output rotation matrix (3x3)</param>
        /// <param name="offset">The output offset (3D vector)</param>
        public static void ComputeRigidMotion(List <Vector3> x, List <Vector3> y, out double[,] R, out double[] offset)
        {
            if (x.Count == 0)
            {
                // Extreme corner case
                R      = AMath.Matrix.Identity(3);
                offset = new double[] { 0, 0, 0 };
                return;
            }

            double[,] X = new double[x.Count, 3];
            double[,] Y = new double[y.Count, 3];
            for (int i = 0; i < x.Count; i++)
            {
                X[i, 0] = x[i][0];
                X[i, 1] = x[i][1];
                X[i, 2] = x[i][2];

                Y[i, 0] = y[i][0];
                Y[i, 1] = y[i][1];
                Y[i, 2] = y[i][2];
            }
            var Xc  = Accord.Statistics.Measures.Mean(X, 0);
            var Yc  = Accord.Statistics.Measures.Mean(Y, 0);
            var H   = AMath.Matrix.TransposeAndDot(AMath.Elementwise.Subtract(Y, Yc, 0), AMath.Elementwise.Subtract(X, Xc, 0));
            var svd = new AMath.Decompositions.SingularValueDecomposition(H);

            R = AMath.Matrix.DotWithTransposed(svd.RightSingularVectors, svd.LeftSingularVectors);
            if (AMath.Matrix.Determinant(R) < 0) // Check whether the determinant is -1
            {
                // We have an improper rotation, i.e. a reflection transformation.
                double[,] V = svd.RightSingularVectors;

                V[0, 2] *= -1;
                V[1, 2] *= -1;
                V[2, 2] *= -1;
                R        = AMath.Matrix.DotWithTransposed(V, svd.LeftSingularVectors); // Now the determinant is +1
            }

            offset = AMath.Elementwise.Subtract(Yc, AMath.Matrix.Dot(Xc, R));
        }
Exemple #2
0
        public override void Init(IRepository repository)
        {
            authorByRevision = repository.SelectionDSL()
                               .Commits().TillRevision(model.PredictionRelease)
                               .ToDictionary(x => x.Revision, x => x.Author);

            int releaseRevisionOrderedNumber = repository.Queryable <Commit>()
                                               .Single(x => x.Revision == model.PredictionRelease).OrderedNumber;
            var codeByAuthorAndFile =
                (
                    from cb in repository.Queryable <CodeBlock>()
                    join m in repository.Queryable <Modification>() on cb.ModificationID equals m.ID
                    join c in repository.Queryable <Commit>() on m.CommitID equals c.ID
                    join f in repository.Queryable <ProjectFile>() on m.FileID equals f.ID
                    where
                    cb.Size > 0
                    &&
                    c.OrderedNumber <= releaseRevisionOrderedNumber
                    group cb by new { Author = c.Author, FileID = f.ID } into g
                    select new
            {
                Author = g.Key.Author,
                FileID = g.Key.FileID,
                CodeSize = g.Sum(x => x.Size)
            }
                ).ToArray();

            var allFiles   = model.AllFiles.Select(x => x.ID).ToArray();
            var allAuthors = repository.SelectionDSL()
                             .Commits().TillRevision(model.PredictionRelease)
                             .Select(x => x.Author).Distinct().ToArray();

            int numberOfFiles     = allFiles.Count();
            int numberOfAuthors   = allAuthors.Count();
            int numberOfEquations = numberOfFiles + numberOfAuthors + 1;

            double[,] equations = new double[numberOfEquations, numberOfEquations];
            double[] results = new double[numberOfEquations];

            int    equation = 0;
            double locAdded = codeByAuthorAndFile.Sum(x => x.CodeSize);

            for (int i = 0; i < allFiles.Length; i++)
            {
                double locAddedInFile = codeByAuthorAndFile
                                        .Where(x => x.FileID == allFiles[i])
                                        .Sum(x => x.CodeSize);
                equations[numberOfEquations - 1, i] = locAddedInFile / locAdded;
                equations[equation, i] = 1;

                if (locAddedInFile > 0)
                {
                    double dcd = repository.SelectionDSL()
                                 .Commits()
                                 .TillRevision(model.PredictionRelease)
                                 .Files()
                                 .IdIs(allFiles[i])
                                 .Modifications().InCommits().InFiles()
                                 .CodeBlocks().InModifications().CalculateDefectCodeDensity(model.PredictionRelease);

                    for (int j = 0; j < allAuthors.Length; j++)
                    {
                        double locAddedInFileByAuthor = codeByAuthorAndFile
                                                        .Where(x => x.FileID == allFiles[i] && x.Author == allAuthors[j])
                                                        .Sum(x => x.CodeSize);
                        equations[equation, numberOfFiles + j] = (locAddedInFileByAuthor / locAddedInFile);
                    }
                    results[equation] = dcd;
                }
                equation++;
            }

            for (int i = 0; i < allAuthors.Length; i++)
            {
                double locAddedByAuthor = codeByAuthorAndFile
                                          .Where(x => x.Author == allAuthors[i])
                                          .Sum(x => x.CodeSize);
                equations[numberOfEquations - 1, numberOfFiles + i] = locAddedByAuthor / locAdded;
                equations[equation, numberOfFiles + i] = 1;

                if (locAddedByAuthor > 0)
                {
                    double dcd = repository.SelectionDSL()
                                 .Commits()
                                 .AuthorIs(allAuthors[i])
                                 .TillRevision(model.PredictionRelease)
                                 .Modifications().InCommits()
                                 .CodeBlocks().InModifications().CalculateDefectCodeDensity(model.PredictionRelease);
                    for (int j = 0; j < allFiles.Length; j++)
                    {
                        double locAddedByAuthorInFile = codeByAuthorAndFile
                                                        .Where(x => x.Author == allAuthors[i] && x.FileID == allFiles[j])
                                                        .Sum(x => x.CodeSize);
                        equations[equation, j] = (locAddedByAuthorInFile / locAddedByAuthor);
                    }
                    results[equation] = dcd;
                }
                equation++;
            }

            results[numberOfEquations - 1] = repository.SelectionDSL()
                                             .Commits()
                                             .TillRevision(model.PredictionRelease)
                                             .Modifications().InCommits()
                                             .CodeBlocks().InModifications().CalculateDefectCodeDensity(model.PredictionRelease);

            int varCount = equations.GetUpperBound(1) + 1;

            double[,] normalEquations = new double[varCount, varCount];
            double[] normalResults = new double[varCount];
            Func <double[, ], double[], int, int, double> nc = (e, r, n1, n2) =>
            {
                double sum = 0;
                for (int i = 0; i < numberOfEquations; i++)
                {
                    if (n2 < numberOfEquations)
                    {
                        sum += e[i, n1] * e[i, n2];
                    }
                    else
                    {
                        sum += e[i, n1] * r[i];
                    }
                }
                return(sum);
            };

            for (int i = 0; i < varCount; i++)
            {
                for (int j = 0; j < varCount; j++)
                {
                    normalEquations[i, j] = nc(equations, results, i, j);
                }
                normalResults[i] = nc(equations, results, i, numberOfEquations);
            }
            var DCD = new Accord.Math.Decompositions.SingularValueDecomposition(normalEquations).Solve(normalResults);

            DCDF = new Dictionary <int, double>();
            DCDA = new Dictionary <string, double>();
            double DCD_min = 0.001;

            for (int i = 0; i < allFiles.Length; i++)
            {
                DCDF.Add(allFiles[i], DCD[i] > 0 ? DCD[i] : DCD_min);
            }
            for (int i = 0; i < allAuthors.Length; i++)
            {
                DCDA.Add(allAuthors[i], DCD[numberOfFiles + i] > 0 ? DCD[numberOfFiles + i] : DCD_min);
            }
        }
        public override void Init(IRepositoryResolver repositories)
        {
            authorByRevision = repositories.SelectionDSL()
                .Commits().TillRevision(model.PredictionRelease)
                .ToDictionary(x => x.Revision, x => x.Author);

            int releaseRevisionOrderedNumber = repositories.Repository<Commit>()
                .Single(x => x.Revision == model.PredictionRelease).OrderedNumber;
            var codeByAuthorAndFile =
                (
                    from cb in repositories.Repository<CodeBlock>()
                    join m in repositories.Repository<Modification>() on cb.ModificationID equals m.ID
                    join c in repositories.Repository<Commit>() on m.CommitID equals c.ID
                    join f in repositories.Repository<ProjectFile>() on m.FileID equals f.ID
                    where
                        cb.Size > 0
                        &&
                        c.OrderedNumber <= releaseRevisionOrderedNumber
                    group cb by new { Author = c.Author, FileID = f.ID } into g
                    select new
                    {
                        Author = g.Key.Author,
                        FileID = g.Key.FileID,
                        CodeSize = g.Sum(x => x.Size)
                    }
                ).ToArray();

            var allFiles = model.AllFiles.Select(x => x.ID).ToArray();
            var allAuthors = repositories.SelectionDSL()
                .Commits().TillRevision(model.PredictionRelease)
                .Select(x => x.Author).Distinct().ToArray();

            int numberOfFiles = allFiles.Count();
            int numberOfAuthors = allAuthors.Count();
            int numberOfEquations = numberOfFiles + numberOfAuthors + 1;
            double[,] equations = new double[numberOfEquations,numberOfEquations];
            double[] results = new double[numberOfEquations];

            int equation = 0;
            double locAdded = codeByAuthorAndFile.Sum(x => x.CodeSize);

            for (int i = 0; i < allFiles.Length; i++)
            {
                double locAddedInFile = codeByAuthorAndFile
                    .Where(x => x.FileID == allFiles[i])
                    .Sum(x => x.CodeSize);
                equations[numberOfEquations-1, i] = locAddedInFile / locAdded;
                equations[equation, i] = 1;

                if (locAddedInFile > 0)
                {
                    double dcd = repositories.SelectionDSL()
                        .Commits()
                            .TillRevision(model.PredictionRelease)
                        .Files()
                            .IdIs(allFiles[i])
                        .Modifications().InCommits().InFiles()
                        .CodeBlocks().InModifications().CalculateDefectCodeDensity(model.PredictionRelease);

                    for (int j = 0; j < allAuthors.Length; j++)
                    {
                        double locAddedInFileByAuthor = codeByAuthorAndFile
                            .Where(x => x.FileID == allFiles[i] && x.Author == allAuthors[j])
                            .Sum(x => x.CodeSize);
                        equations[equation, numberOfFiles + j] = (locAddedInFileByAuthor / locAddedInFile);
                    }
                    results[equation] = dcd;
                }
                equation++;
            }

            for (int i = 0; i < allAuthors.Length; i++)
            {
                double locAddedByAuthor = codeByAuthorAndFile
                    .Where(x => x.Author == allAuthors[i])
                    .Sum(x => x.CodeSize);
                equations[numberOfEquations-1, numberOfFiles + i] = locAddedByAuthor / locAdded;
                equations[equation, numberOfFiles + i] = 1;

                if (locAddedByAuthor > 0)
                {
                    double dcd = repositories.SelectionDSL()
                        .Commits()
                            .AuthorIs(allAuthors[i])
                            .TillRevision(model.PredictionRelease)
                        .Modifications().InCommits()
                        .CodeBlocks().InModifications().CalculateDefectCodeDensity(model.PredictionRelease);
                    for (int j = 0; j < allFiles.Length; j++)
                    {
                        double locAddedByAuthorInFile = codeByAuthorAndFile
                            .Where(x => x.Author == allAuthors[i] && x.FileID == allFiles[j])
                            .Sum(x => x.CodeSize);
                        equations[equation, j] = (locAddedByAuthorInFile / locAddedByAuthor);
                    }
                    results[equation] = dcd;
                }
                equation++;
            }

            results[numberOfEquations-1] = repositories.SelectionDSL()
                .Commits()
                    .TillRevision(model.PredictionRelease)
                .Modifications().InCommits()
                .CodeBlocks().InModifications().CalculateDefectCodeDensity(model.PredictionRelease);

            int varCount = equations.GetUpperBound(1)+1;
            double[,] normalEquations = new double[varCount, varCount];
            double[] normalResults = new double[varCount];
            Func<double[,],double[],int,int,double> nc = (e, r, n1, n2) =>
            {
                double sum = 0;
                for (int i = 0; i < numberOfEquations; i++)
                {
                    if (n2 < numberOfEquations)
                    {
                        sum += e[i,n1] * e[i,n2];
                    }
                    else
                    {
                        sum += e[i,n1] * r[i];
                    }
                }
                return sum;
            };

            for (int i = 0; i < varCount; i++)
            {
                for (int j = 0; j < varCount; j++)
                {
                    normalEquations[i,j] = nc(equations,results,i,j);
                }
                normalResults[i] = nc(equations,results,i,numberOfEquations);
            }
            var DCD = new Accord.Math.Decompositions.SingularValueDecomposition(normalEquations).Solve(normalResults);

            DCDF = new Dictionary<int,double>();
            DCDA = new Dictionary<string,double>();
            double DCD_min = 0.001;
            for (int i = 0; i < allFiles.Length; i++)
            {
                DCDF.Add(allFiles[i], DCD[i] > 0 ? DCD[i] : DCD_min);
            }
            for (int i = 0; i < allAuthors.Length; i++)
            {
                DCDA.Add(allAuthors[i], DCD[numberOfFiles + i] > 0 ? DCD[numberOfFiles + i] : DCD_min);
            }
        }
Exemple #4
0
 private static void svdUsingAccord(double[,] matrix)
 {
     var svdd = new Accord.Math.Decompositions.SingularValueDecomposition(matrix);
     //svd.U() * svd.W() * svd.VT()
 }