Example #1
0
        void PreCalculate() {
            if (dataset == null)
                return;

            // Extract the relevant data table.
            var bs = dataset.BodyList;
            INumberTable nt = dataset.GetNumberTableView();
            toIdx = Enumerable.Range(0, bs.Count).Where(i => !bs[i].Disabled).ToArray();    // Indexes of enabled bodies.
            int N = nt.Rows - pcaSamples;
            int[] enabledRows = toIdx.Where(i => i < N).ToArray();

            if (enabledRows.Length == 0) 
                throw new TException("No data available!");
            P = new float[enabledRows.Length][];
            MT.Loop(0, P.Length, row => {
                float[] R = P[row] = new float[nt.Columns];
                double[] dsR = nt.Matrix[enabledRows[row]] as double[];
                for (int col = 0; col < nt.Columns; col++)
                    R[col] = (float)dsR[col];
            });

            // Reverse toIdx;
            int[] rIdx = Enumerable.Repeat(-1, bs.Count).ToArray();
            for (int i = 0; i < toIdx.Length; i++) rIdx[toIdx[i]] = i;
            toIdx = rIdx;

            using (var gpu = new VisuMap.DxShader.GpuDevice())
                dtP = DualAffinity.DotProduct(gpu, P, false);

            float[] singValues = new float[pcaMax];
            float[][] PC = FastPca.DoFastReduction(P, pcaMax, singValues, true); 
            P = VisuMap.MathUtil.NewMatrix<float>(PC.Length, pcaSamples);  // P now links data points with the injected points on the main PCA axis.
            float span = 4.0f * singValues[0];
            stepSize = span / (pcaSamples - 1);
            float x0 = - 0.5f * span;
            MT.ForEach(PC, (R, row) => {
                double yy = R.Skip(1).Sum(v => v * v);
                for (int col = 0; col < pcaSamples; col++) {
                    double x = R[0] - (x0 + col * stepSize);
                    P[row][col] = (float)Math.Sqrt(x * x + yy);
                }
            });
        }
Example #2
0
        void PreCalculate()
        {
            if (dataset != null)
            {
                var          bs    = dataset.BodyList;
                INumberTable nt    = dataset.GetNumberTableView();
                int          nrows = nt.Rows - nt.Columns;
                toIdx = Enumerable.Range(0, bs.Count).Where(i => !bs[i].Disabled).ToArray();    // Indexes of enabled bodies.
                int[] selectedRows    = toIdx.Where(i => i < nrows).ToArray();
                int[] selectedColumns = toIdx.Where(i => i >= nrows).Select(i => i - nrows).ToArray();

                if ((selectedColumns.Length == 0) || (selectedRows.Length == 0))
                {
                    throw new TException("No-zero number of genes and cells must be selected!");
                }
                P = new float[selectedRows.Length][];
                MT.Loop(0, P.Length, row => {
                    float[] R    = P[row] = new float[selectedColumns.Length];
                    double[] dsR = nt.Matrix[selectedRows[row]] as double[];
                    for (int col = 0; col < selectedColumns.Length; col++)
                    {
                        R[col] = (float)dsR[selectedColumns[col]];
                    }
                });

                // Reverse toIdx;
                int[] rIdx = Enumerable.Repeat(-1, bs.Count).ToArray();
                for (int i = 0; i < toIdx.Length; i++)
                {
                    rIdx[toIdx[i]] = i;
                }
                toIdx = rIdx;
            }
            float[][] Q = Transpose(P);   // Q is the transpose of P.

            // Calculate the distance tables for P and Q.
            bool isPCor = (metricMode == MetricMode.CorCor) || (metricMode == MetricMode.CorEuc);
            bool isQCor = (metricMode == MetricMode.CorCor) || (metricMode == MetricMode.EucCor);

            if (isPCor)
            {
                Normalize(P);
            }
            if (isQCor)
            {
                Normalize(Q);
            }

            using (var gpu = new VisuMap.DxShader.GpuDevice())
                using (var cc = gpu.CreateConstantBuffer <ShaderConstant>(0))
                    using (var sd = gpu.LoadShader("SingleCellAnalysis.DotProduct.cso", Assembly.GetExecutingAssembly())) {
                        dtP = CallShadere(gpu, cc, sd, P, isPCor);
                        dtQ = CallShadere(gpu, cc, sd, Q, isQCor);
                    }

            /*
             * affinity-propagation enhances structure if colums or rows within clusters are
             * light occupied with high randomness. AP however dilutes clusters with few members.
             * For instance, singlton gene cluster (with only gene) will suppressed by AP due to
             * its aggregation with neighboring genes (which should be consdiered as separate
             * clusters.)
             *
             * ProbagateAffinity(dtQ, P); // Column<->Column affinity => Column->Row affinity
             * ProbagateAffinity(dtP, Q);  // Row<->Row affinity => Row->Column affinity.
             */

            // Calculates the distance between rows and columns into P.
            P = AffinityToDistance(P, Q);
            Q = null;
            var    app      = SingleCellPlugin.App.ScriptApp;
            double linkBias = app.GetPropertyAsDouble("SingleCell.Separation", 1.0);
            double pScale   = app.GetPropertyAsDouble("SingleCell.CellScale", 1.0);
            double qScale   = app.GetPropertyAsDouble("SingleCell.GeneScale", 1.0);
            //PowerMatrix(P, linkBias);

            // Scaling dtP, dtQ to the range of P.
            Func <float[][], float> aFct = AverageSqrt;
            double av = aFct(P);

            pScale *= av / aFct(dtP);
            qScale *= av / aFct(dtQ);
            ScaleMatrix(dtP, pScale);
            ScaleMatrix(dtQ, qScale);

            //ScaleMatrix(P, linkBias);
            ShiftMatrix(P, (float)(linkBias * av));
        }