Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="A"></param>
        /// <param name="indexes"></param>
        /// <param name="work"></param>
        /// <returns></returns>
        public static DoubleMatrix1D Permute(DoubleMatrix1D A, int[] indexes, double[] work)
        {
            // check validity
            int size = A.Size;

            if (indexes.Length != size)
            {
                throw new IndexOutOfRangeException("invalid permutation");
            }

            /*
             * int i=size;
             * int a;
             * while (--i >= 0 && (a=indexes[i])==i) if (a < 0 || a >= size) throw new IndexOutOfRangeException("invalid permutation");
             * if (i<0) return; // nothing to permute
             */

            if (work == null || size > work.Length)
            {
                work = A.ToArray();
            }
            else
            {
                A.ToArray(ref work);
            }
            for (int i = size; --i >= 0;)
            {
                A[i] = work[indexes[i]];
            }
            return(A);
        }
        /// <summary>
        /// Update the SVD with the addition of a new column.
        /// </summary>
        /// <param name="c">
        /// The new column.
        /// </param>
        /// <param name="wantV">
        /// Whether the matrix V is needed.
        /// </param>
        public void Update(DoubleMatrix1D c, bool wantV)
        {
            int nRows = c.Size - _m;

            if (nRows > 0)
            {
                _u = DoubleFactory2D.Dense.AppendRows(_u, new SparseDoubleMatrix2D(nRows, _n));
                _m = c.Size;
            }
            else if (nRows < 0)
            {
                c = DoubleFactory1D.Sparse.AppendColumns(c, DoubleFactory1D.Sparse.Make(-nRows));
            }

            var d = DoubleFactory2D.Dense.Make(c.ToArray(), c.Size);

            // l = U'd is the eigencoding of d
            var l = _u.ViewDice().ZMult(d, null);

            ////var uu = _u.ZMult(_u.ViewDice(), null);

            // Ul = UU'd
            ////var ul = uu.ZMult(d, null);
            var ul = _u.ZMult(l, null);

            // h = d - UU'd = d - Ul is the component of d orthogonal to the subspace spanned by U
            ////var h = d.Copy().Assign(uu.ZMult(d, null), BinaryFunctions.Minus);
            ////var h = d.Copy().Assign(ul, BinaryFunctions.Minus);

            // k is the projection of d onto the subspace othogonal to U
            var k = Math.Sqrt(d.Aggregate(BinaryFunctions.Plus, a => a * a) - (2 * l.Aggregate(BinaryFunctions.Plus, a => a * a)) + ul.Aggregate(BinaryFunctions.Plus, a => a * a));

            // truncation
            if (k == 0 || double.IsNaN(k))
            {
                return;
            }

            _n++;

            // j = d - UU'd = d - Ul is an orthogonal basis for the component of d orthogonal to the subspace spanned by U
            ////var j = h.Assign(UnaryFunctions.Div(k));
            var j = d.Assign(ul, BinaryFunctions.Minus).Assign(UnaryFunctions.Div(k));

            // Q = [ S, l; 0, ||h||]
            var q =
                DoubleFactory2D.Sparse.Compose(
                    new[] { new[] { S, l }, new[] { null, DoubleFactory2D.Dense.Make(1, 1, k) } });

            var svdq = new SingularValueDecomposition(q, true, wantV, true);

            _u = DoubleFactory2D.Dense.AppendColumns(_u, j).ZMult(svdq.U, null);
            _s = svdq.SingularValues;
            if (wantV)
            {
                _v = DoubleFactory2D.Dense.ComposeDiagonal(_v, DoubleFactory2D.Dense.Identity(1)).ZMult(
                    svdq.V, null);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// 3-d OLAP cube operator; Fills all cells of the given vectors into the given histogram.
        /// If you use Hep.Aida.Ref.Converter.ToString(histo) on the result, the OLAP cube of x-"column" vsd y-"column" vsd z-"column", summing the weights "column" will be printed.
        /// For example, aggregate sales by product by region by time.
        /// <p>
        /// Computes the distinct values of x and y and z, yielding histogram axes that capture one distinct value per bin.
        /// Then fills the histogram.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="weights"></param>
        /// <returns>the histogram containing the cube.</returns>
        /// <excption cref="ArgumentException">if <i>x.Count != y.Count || x.Count != z.Count || x.Count != weights.Count</i>.</excption>
        public static Hep.Aida.IHistogram3D cube(DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix1D z, DoubleMatrix1D weights)
        {
            if (x.Size != y.Size || x.Size != z.Size || x.Size != weights.Size)
            {
                throw new ArgumentException("vectors must have same size");
            }

            var epsilon  = 1.0E-9;
            var distinct = new DoubleArrayList();
            var vals     = new double[x.Size];
            var sorted   = new DoubleArrayList(vals);

            // compute distinct values of x
            vals = x.ToArray(); // copy x into vals
            sorted.Sort();
            Cern.Jet.Stat.Descriptive.Frequencies(sorted, distinct, null);
            // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
            if (distinct.Count > 0)
            {
                distinct.Add(distinct[distinct.Count - 1] + epsilon);
            }
            distinct.TrimToSize();
            Hep.Aida.IAxis xaxis = new Hep.Aida.Ref.VariableAxis(distinct.ToArray());

            // compute distinct values of y
            vals = y.ToArray();
            sorted.Sort();
            Cern.Jet.Stat.Descriptive.Frequencies(sorted, distinct, null);
            // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
            if (distinct.Count > 0)
            {
                distinct.Add(distinct[distinct.Count - 1] + epsilon);
            }
            distinct.TrimToSize();
            Hep.Aida.IAxis yaxis = new Hep.Aida.Ref.VariableAxis(distinct.ToArray());

            // compute distinct values of z
            vals = z.ToArray();
            sorted.Sort();
            Cern.Jet.Stat.Descriptive.Frequencies(sorted, distinct, null);
            // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
            if (distinct.Count > 0)
            {
                distinct.Add(distinct[distinct.Count - 1] + epsilon);
            }
            distinct.TrimToSize();
            Hep.Aida.IAxis zaxis = new Hep.Aida.Ref.VariableAxis(distinct.ToArray());

            Hep.Aida.IHistogram3D histo = new Hep.Aida.Ref.Histogram3D("Cube", xaxis, yaxis, zaxis);
            return(Histogram(histo, x, y, z, weights));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SingularValueDecomposition"/> class with a vector (the first column).
 /// </summary>
 /// <param name="arg">
 /// A vector.
 /// </param>
 /// <exception cref="ArgumentException">
 /// If <code>a.Rows &lt; a.Columns</code>.
 /// </exception>
 public SingularValueDecomposition(DoubleMatrix1D arg)
 {
     BatchSVD(DoubleFactory2D.Dense.Make(arg.ToArray(), arg.Size), true, true, true);
 }