コード例 #1
0
ファイル: VisualizationUtils.cs プロジェクト: 0000duck/latino
        // *** Layout utils ***

        // *** experimental
        public static Bitmap __DrawElevation__(IEnumerable <Vector2D> layout, LayoutSettings layoutSettings, int matrixRows, int matrixCols)
        {
            double[,] elevData = ComputeLayoutElevation(layout, layoutSettings, matrixRows, matrixCols);
            Bitmap   bmp   = new Bitmap((int)Math.Ceiling(layoutSettings.Width), (int)Math.Ceiling(layoutSettings.Height));
            Graphics gfx   = Graphics.FromImage(bmp);
            Vector2D pixSz = new Vector2D(layoutSettings.Width / (double)matrixCols, layoutSettings.Height / (double)matrixRows);
            int      row   = 0;
            int      oldY  = 0;

            for (double y = pixSz.Y; row < elevData.GetLength(0); row++, y += pixSz.Y)
            {
                int _y   = (int)Math.Round(y);
                int col  = 0;
                int oldX = 0;
                for (double x = pixSz.X; col < elevData.GetLength(1); col++, x += pixSz.X)
                {
                    int   _x    = (int)Math.Round(x);
                    Brush brush = new SolidBrush(Color.FromArgb(255, 0, 0, (int)Math.Round(255.0 * elevData[row, col])));
                    gfx.FillRectangle(brush, oldX, oldY, _x - oldX, _y - oldY);
                    brush.Dispose();
                    oldX = _x;
                }
                oldY = _y;
            }
            return(bmp);
        }
コード例 #2
0
ファイル: VisualizationUtils.cs プロジェクト: 0000duck/latino
        public static double[,] ComputeLayoutElevation(IEnumerable <Vector2D> layout, LayoutSettings layoutSettings, int matrixRows, int matrixCols,
                                                       double sigma, double r, bool normalize, bool cut, double cutStdevMult)
        {
            Utils.ThrowException(layout == null ? new ArgumentNullException("layout") : null);
            Utils.ThrowException(layoutSettings == null ? new ArgumentNullException("layoutSettings") : null);
            Utils.ThrowException(matrixRows < 1 ? new ArgumentOutOfRangeException("matrixRows") : null);
            Utils.ThrowException(matrixCols < 1 ? new ArgumentOutOfRangeException("matrixCols") : null);
            Utils.ThrowException(sigma <= 0 ? new ArgumentOutOfRangeException("sigma") : null);
            LayoutSettings nrmLayoutSettings = layoutSettings.Clone();
            double         fX = 1.0 / (layoutSettings.Width - 2.0 * layoutSettings.MarginHoriz);
            double         fY = 1.0 / (layoutSettings.Height - 2.0 * layoutSettings.MarginVert);

            nrmLayoutSettings.Width       *= fX;
            nrmLayoutSettings.MarginHoriz *= fX;
            nrmLayoutSettings.Height      *= fY;
            nrmLayoutSettings.MarginVert  *= fY;
            Vector2D[]  nrmLayout   = nrmLayoutSettings.AdjustLayout(layout);
            LayoutIndex layoutIndex = new LayoutIndex();

            layoutIndex.MaxPointsPerLeaf = 100; // *** hardcoded max points per leaf
            if (r > 0)
            {
                layoutIndex.BuildIndex(nrmLayout);
            }
            double[,] zMtx = new double[matrixRows, matrixCols];
            Vector2D pixSz = new Vector2D(nrmLayoutSettings.Width / (double)matrixCols, nrmLayoutSettings.Height / (double)matrixRows);
            double   maxZ  = 0;
            double   avgZ  = 0;
            int      row   = 0;

            for (double y = pixSz.Y / 2.0; y < nrmLayoutSettings.Height; y += pixSz.Y, row++)
            {
                int col = 0;
                for (double x = pixSz.X / 2.0; x < nrmLayoutSettings.Width; x += pixSz.X, col++)
                {
                    Vector2D pt0 = new Vector2D(x, y);
                    double   z   = 0;
                    if (r <= 0)
                    {
                        foreach (Vector2D pt in nrmLayout)
                        {
                            double dist = (pt - pt0).GetLength();
                            z += Math.Exp(-sigma * dist * dist);
                        }
                    }
                    else
                    {
                        foreach (IdxDat <Vector2D> pt in layoutIndex.GetPoints(pt0, r))
                        {
                            double dist = (pt.Dat - pt0).GetLength();
                            z += Math.Exp(-sigma * dist * dist);
                        }
                    }
                    zMtx[row, col] = z;
                    if (z > maxZ)
                    {
                        maxZ = z;
                    }
                    avgZ += z;
                }
            }
            avgZ /= (double)(matrixRows * matrixCols);
            if (avgZ > 0)
            {
                if (cut)
                {
                    double stdev = 0;
                    for (row = 0; row < zMtx.GetLength(0); row++)
                    {
                        for (int col = 0; col < zMtx.GetLength(1); col++)
                        {
                            stdev += (zMtx[row, col] - avgZ) * (zMtx[row, col] - avgZ);
                        }
                    }
                    stdev = Math.Sqrt(stdev / (double)(matrixRows * matrixCols));
                    maxZ  = avgZ + stdev * cutStdevMult;
                    for (row = 0; row < zMtx.GetLength(0); row++)
                    {
                        for (int col = 0; col < zMtx.GetLength(1); col++)
                        {
                            if (zMtx[row, col] > maxZ)
                            {
                                zMtx[row, col] = maxZ;
                            }
                        }
                    }
                }
                if (normalize && maxZ > 0)
                {
                    for (row = 0; row < zMtx.GetLength(0); row++)
                    {
                        for (int col = 0; col < zMtx.GetLength(1); col++)
                        {
                            zMtx[row, col] /= maxZ;
                        }
                    }
                }
            }
            return(zMtx);
        }
コード例 #3
0
ファイル: VisualizationUtils.cs プロジェクト: 0000duck/latino
 public static double[,] ComputeLayoutElevation(IEnumerable <Vector2D> layout, LayoutSettings layoutSettings, int matrixRows, int matrixCols)
 {
     return(ComputeLayoutElevation(layout, layoutSettings, matrixRows, matrixCols, /*sigma=*/ 500, /*r=*/ 0.1, /*normalize=*/ true, /*cut=*/ false, 2));
 }
コード例 #4
0
        public Vector2D[] ComputeLayout(LayoutSettings settings)
        {
            UnlabeledDataset <SparseVector <double> > dataset = new UnlabeledDataset <SparseVector <double> >(mDataset);

            // clustering
            mLogger.Info("ComputeLayout", "Clustering ...");
            KMeansFast kMeans = new KMeansFast(mKClust);

            kMeans.Eps    = mKMeansEps;
            kMeans.Random = mRandom;
            kMeans.Trials = 1;
            ClusteringResult clustering = kMeans.Cluster(mDataset); // throws ArgumentValueException
            // determine reference instances
            UnlabeledDataset <SparseVector <double> > dsRefInst = new UnlabeledDataset <SparseVector <double> >();

            foreach (Cluster cluster in clustering.Roots)
            {
                SparseVector <double> centroid
                    = cluster.Items.Count > 0 ? cluster.ComputeCentroid(mDataset, CentroidType.NrmL2) : new SparseVector <double>();
                dsRefInst.Add(centroid); // dataset of reference instances
                dataset.Add(centroid);   // add centroids to the main dataset
            }
            // position reference instances
            mLogger.Info("ComputeLayout", "Positioning reference instances ...");
            SparseMatrix <double>    simMtx = ModelUtils.GetDotProductSimilarity(dsRefInst, mSimThresh, /*fullMatrix=*/ false);
            StressMajorizationLayout sm     = new StressMajorizationLayout(dsRefInst.Count, new DistFunc(simMtx));

            sm.Random = mRandom;
            Vector2D[] centrPos = sm.ComputeLayout();
            // k-NN
            mLogger.Info("ComputeLayout", "Computing similarities ...");
            simMtx = ModelUtils.GetDotProductSimilarity(dataset, mSimThresh, /*fullMatrix=*/ true);
            mLogger.Info("ComputeLayout", "Constructing system of linear equations ...");
            LabeledDataset <double, SparseVector <double> > lsqrDs = new LabeledDataset <double, SparseVector <double> >();

            foreach (IdxDat <SparseVector <double> > simMtxRow in simMtx)
            {
                if (simMtxRow.Dat.Count <= 1)
                {
                    mLogger.Warn("ComputeLayout", "Instance #{0} has no neighborhood.", simMtxRow.Idx);
                }
                ArrayList <KeyDat <double, int> > knn = new ArrayList <KeyDat <double, int> >(simMtxRow.Dat.Count);
                foreach (IdxDat <double> item in simMtxRow.Dat)
                {
                    if (item.Idx != simMtxRow.Idx)
                    {
                        knn.Add(new KeyDat <double, int>(item.Dat, item.Idx));
                    }
                }
                knn.Sort(DescSort <KeyDat <double, int> > .Instance);
                int count = Math.Min(knn.Count, mKNN);
                SparseVector <double> eq = new SparseVector <double>();
                double wgt = 1.0 / (double)count;
                for (int i = 0; i < count; i++)
                {
                    eq.InnerIdx.Add(knn[i].Dat);
                    eq.InnerDat.Add(-wgt);
                }
                eq.InnerIdx.Sort(); // *** sort only indices
                eq[simMtxRow.Idx] = 1;
                lsqrDs.Add(0, eq);
            }
            Vector2D[] layout = new Vector2D[dataset.Count - mKClust];
            for (int i = dataset.Count - mKClust, j = 0; i < dataset.Count; i++, j++)
            {
                SparseVector <double> eq = new SparseVector <double>(new IdxDat <double>[] { new IdxDat <double>(i, 1) });
                lsqrDs.Add(centrPos[j].X, eq);
            }
            LSqrModel lsqr = new LSqrModel();

            lsqr.Train(lsqrDs);
            for (int i = 0; i < layout.Length; i++)
            {
                layout[i].X = lsqr.Solution[i];
            }
            for (int i = lsqrDs.Count - mKClust, j = 0; i < lsqrDs.Count; i++, j++)
            {
                lsqrDs[i].Label = centrPos[j].Y;
            }
            lsqr.Train(lsqrDs);
            for (int i = 0; i < layout.Length; i++)
            {
                layout[i].Y = lsqr.Solution[i];
            }
            return(settings == null ? layout : settings.AdjustLayout(layout));
        }
コード例 #5
0
        public Vector2D[] ComputeLayout(LayoutSettings settings, Vector2D[] initLayout)
        {
            if (settings == null)
            {
                settings = new LayoutSettings();
            }
            if (mNumPoints == 1)
            {
                return(settings.AdjustLayout(new Vector2D[] { new Vector2D() }));
            }                                                                                         // trivial case
            const double eps = 0.00001;

            Vector2D[] layout = new Vector2D[mNumPoints];
            // initialize layout
            if (initLayout != null)
            {
                int initLen = Math.Min(mNumPoints, initLayout.Length);
                Array.Copy(initLayout, layout, initLen);
                for (int i = initLayout.Length; i < mNumPoints; i++)
                {
                    layout[i] = new Vector2D(mRnd.NextDouble(), mRnd.NextDouble());
                }
            }
            else
            {
                for (int i = 0; i < mNumPoints; i++)
                {
                    layout[i] = new Vector2D(mRnd.NextDouble(), mRnd.NextDouble());
                }
            }
            // main optimization loop
            double globalStress = 0, stressDiff = 0;
            double oldGlobalStress = double.MaxValue;

            for (int step = 0; step < mMaxSteps; step++)
            {
                globalStress = 0;
                for (int i = 0; i < mNumPoints; i++)
                {
                    double   div    = 0;
                    Vector2D newPos = new Vector2D(0, 0);
                    for (int j = 0; j < mNumPoints; j++)
                    {
                        if (i != j)
                        {
                            double dIj = mDistFunc.GetDistance(i, j);
                            if (dIj < eps)
                            {
                                dIj = eps;
                            }
                            double wIj       = 1.0 / Math.Pow(dIj, 2);
                            double xIMinusXJ = layout[i].X - layout[j].X;
                            double yIMinusYJ = layout[i].Y - layout[j].Y;
                            double denom     = Math.Sqrt(Math.Pow(xIMinusXJ, 2) + Math.Pow(yIMinusYJ, 2));
                            if (denom < eps)
                            {
                                denom = eps;
                            }                                 // avoid dividing by zero
                            div      += wIj;
                            newPos.X += wIj * (layout[j].X + dIj * (xIMinusXJ / denom));
                            newPos.Y += wIj * (layout[j].Y + dIj * (yIMinusYJ / denom));
                            if (i < j)
                            {
                                Vector2D diff = layout[i] - layout[j];
                                globalStress += wIj * Math.Pow(diff.GetLength() - dIj, 2);
                            }
                        }
                    }
                    layout[i].X = newPos.X / div;
                    layout[i].Y = newPos.Y / div;
                }
                stressDiff = oldGlobalStress - globalStress;
                if ((step - 1) % 100 == 0)
                {
                    mLogger.Info("ComputeLayout", "Global stress: {0:0.00} Diff: {1:0.0000}", globalStress, stressDiff);
                }
                oldGlobalStress = globalStress;
                if (stressDiff <= mMinDiff)
                {
                    break;
                }
            }
            mLogger.Info("ComputeLayout", "Final global stress: {0:0.00} Diff: {1:0.0000}", globalStress, stressDiff);
            return(settings.AdjustLayout(layout));
        }
コード例 #6
0
 public Vector2D[] ComputeLayout(LayoutSettings settings)
 {
     return(ComputeLayout(settings, /*initLayout=*/ null));
 }