Exemple #1
0
        public static Tensor Expand(this Session session, Tensor x, int axis)
        {
            const string ActionName = "expand";

            if (axis < 0)
            {
                throw new ArgumentException(Properties.Resources.E_NegativeAxisIndex, nameof(axis));
            }

            return(session.RunOperation(
                       ActionName,
                       () =>
            {
                bool calculateGradient = session.CalculateGradients && x.CalculateGradient;

                // allocate destination
                Tensor y = session.AllocateTensor(ActionName, x.Shape.InsertAxis(axis, 1), calculateGradient);

                // simply copy tensor content
                Vectors.Copy(x.Length, x.Weights, 0, y.Weights, 0);

#if !NOLEARNING
                if (calculateGradient)
                {
                    // simply copy tensor content
                    session.Push(ActionName, () => x.AddGradient(y.Gradient));
                }
#endif

                return y;
            }));
        }
Exemple #2
0
        private static void Unstack(Tensor x, int axis, IList <Tensor> ys, bool useGradients)
        {
            int xlen     = x.Length;
            int xdim     = x.Axes[axis];
            int xstride0 = x.Strides[axis];                         // axis inner stride
            int xstride1 = axis == 0 ? xlen : x.Strides[axis - 1];  // axis outer stride

            float[] xw = useGradients ? x.Gradient : x.Weights;

            for (int i = 0, offx = 0; i < xdim; i++, offx += xstride0)
            {
                Tensor  y  = ys[i];
                float[] yw = useGradients ? y.Gradient : y.Weights;

                for (int offxx = offx, offy = 0; offxx < xlen; offxx += xstride1, offy += xstride0)
                {
                    if (useGradients)
                    {
                        Mathematics.Add(xstride0, xw, offxx, yw, offy);
                    }
                    else
                    {
                        Vectors.Copy(xstride0, xw, offxx, yw, offy);
                    }
                }
            }
        }
Exemple #3
0
        private static void Split(Tensor x, int axis, IList <Tensor> ys, bool useGradients)
        {
            int xstride = axis == 0 ? x.Length : x.Strides[axis - 1];
            int ydim    = axis == 0 ? 1 : x.Length / xstride;

            float[] xw = useGradients ? x.Gradient : x.Weights;

            for (int i = 0, offx = 0, ii = ys.Count; i < ii; i++)
            {
                Tensor  y       = ys[i];
                float[] yw      = useGradients ? y.Gradient : y.Weights;
                int     ystride = axis == 0 ? y.Length : y.Strides[axis - 1];

                for (int n = 0, offxx = offx, offy = 0; n < ydim; n++, offxx += xstride, offy += ystride)
                {
                    if (useGradients)
                    {
                        Mathematics.Add(ystride, xw, offxx, yw, offy);
                    }
                    else
                    {
                        Vectors.Copy(ystride, xw, offxx, yw, offy);
                    }
                }

                offx += ystride;
            }
        }
Exemple #4
0
        public static Tensor Reshape(this Session session, Tensor x, Shape shape)
        {
            const string ActionName = "reshape";

            // validate new shape
            if (shape.Length != x.Length)
            {
                throw new ArgumentException("The size of new shape must be the same as tensor length.", nameof(shape));
            }

            return(session.RunOperation(
                       ActionName,
                       () =>
            {
                bool calculateGradient = session.CalculateGradients && x.CalculateGradient;

                // allocate destination
                Tensor y = session.AllocateTensor(ActionName, shape, calculateGradient);

                // simply copy tensor content
                Vectors.Copy(x.Length, x.Weights, 0, y.Weights, 0);

#if !NOLEARNING
                if (calculateGradient)
                {
                    // simply copy tensor content
                    session.Push(ActionName, () => x.AddGradient(y.Gradient));
                }
#endif

                return y;
            }));
        }
Exemple #5
0
        private static void CopyArea(Image dst, int xdst, int ydst, int width, int height, Image src, int xsrc, int ysrc)
        {
            ulong[] bitssrc = src.Bits;
            ulong[] bitsdst = dst.Bits;

            int stride1src = src.Stride1;
            int stride1dst = dst.Stride1;

            int offsrc = (ysrc * stride1src) + (xsrc * src.BitsPerPixel);
            int offdst = (ydst * stride1dst) + (xdst * src.BitsPerPixel);

            int count = width * src.BitsPerPixel;

            if (stride1src == stride1dst && xsrc == 0 && xdst == 0 && width == src.Width)
            {
                Vectors.Copy(height * src.Stride, bitssrc, ysrc * src.Stride, bitsdst, ydst * dst.Stride);
            }
            else
            {
                for (int i = 0; i < height; i++, offsrc += stride1src, offdst += stride1dst)
                {
                    BitUtils.CopyBits(count, bitssrc, offsrc, bitsdst, offdst);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Performs initial cluster seeding according to K-Means++ algorithm.
        /// </summary>
        /// <param name="x">The data points <paramref name="x"/> to clusterize.</param>
        /// <param name="weights">The <c>weight</c> of importance for each data point.</param>
        /// <param name="cancellationToken">The cancellationToken token used to notify the clusterizer that the operation should be canceled.</param>
        /// <see href="https://en.wikipedia.org/wiki/K-means++"/>
        internal void KMeansPlusPlusSeeding(IList <IVector <float> > x, IList <float> weights, CancellationToken cancellationToken)
        {
            Random random = new Random(0);

            int k         = this.Count;
            int dimension = this.Dimension;
            int samples   = x.Count;

            // 1. Choose one center uniformly at random from among the data points.
            int idx = random.Next(0, samples);

            x[idx].Copy(this[0].Centroid, 0);

            float[] distances = new float[samples];
            for (int centroid = 1; centroid < k; centroid++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // 2. For each data point x, compute D(x), the distance between x and the nearest center that has already been chosen.
                this.Assign(0, centroid, x, distances, cancellationToken);

                // 3. Choose one new data point at random as a new center,
                // using a weighted probability distribution where a point x is chosen with probability proportional to D(x)^2.
                Vectors.Square(samples, distances, 0);
                float sum = Vectors.Sum(samples, distances, 0);
                if (sum < 1e-10f)
                {
                    // all points are the same
                    for (; centroid < k; centroid++)
                    {
                        Vectors.Copy(dimension, this[0].Centroid, 0, this[centroid].Centroid, 0);
                    }
                }
                else
                {
                    // Choose a point from a weighted probability distribution
                    float randomValue = (float)random.NextDouble() * sum;
                    idx = -1;
                    sum = 0.0f;
                    for (int i = 0; i < samples; i++)
                    {
                        sum += distances[i];
                        if (randomValue < sum)
                        {
                            idx = i;
                            break;
                        }
                    }

                    if (idx == -1)
                    {
                        idx = random.Next(0, samples);
                    }

                    x[idx].Copy(this[centroid].Centroid, 0);
                }

                // 4. Repeat Steps 2 and 3 until k centers have been chosen.
            }
        }
Exemple #7
0
    private int TryFall(Vector3i _blockPos, BlockValue _blockValue)
    {
        int      k   = 0;
        Vector3i pos = Vectors.Copy(_blockPos);
        int      y0  = pos.y;

        for (k = 1; k <= gravity; k++)
        {
            pos.y = y0 - k;
            BlockValue below = GameManager.Instance.World.GetBlock(pos);
            if (below.Equals(BlockValue.Air) || IsEmpty(below.Block))
            {
            }
            else
            {
                k = k - 1;
                break;
            }
        }
        pos.y = y0 - k;
        // There was a gap and < len : insert at new pos
        if (k > 0 && k < gravity)
        {
            GameManager.Instance.World.SetBlockRPC(pos, _blockValue);
        }
        // There was a gap : delete initial
        if (k > 0)
        {
            GameManager.Instance.World.SetBlockRPC(_blockPos, BlockValue.Air);
        }
        return(k);        // -> true if if it felt
        // int mdom = _myBlockValue.damage;
        // this.DamageBlock(GameManager.Instance.World, 0, _myBlockPos, _myBlockValue, 10, -1, false, false);
    }
Exemple #8
0
        private static void Stack(IList <Tensor> xs, int axis, Tensor y, bool useGradients)
        {
            int xdim    = xs.Count;
            int ylen    = y.Length;
            int ystride = y.Strides[axis];

            float[] yw = useGradients ? y.Gradient : y.Weights;

            for (int offx = 0, offy = 0; offy < ylen; offx += ystride)
            {
                for (int i = 0; i < xdim; i++, offy += ystride)
                {
                    Tensor  x  = xs[i];
                    float[] xw = useGradients ? x.Gradient : x.Weights;

                    if (useGradients)
                    {
                        Mathematics.Add(ystride, xw, offx, yw, offy);
                    }
                    else
                    {
                        Vectors.Copy(ystride, xw, offx, yw, offy);
                    }
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Reduces the height of the <see cref="Image"/> by the factor of 2.
        /// </summary>
        /// <returns>The scaled <see cref="Image"/>.</returns>
        public Image Reduce1x2()
        {
            if (this.BitsPerPixel != 1)
            {
                throw new NotSupportedException(Properties.Resources.E_UnsupportedDepth_1bpp);
            }

            Image dst = new Image(
                this.Width,
                (this.Height + 1) >> 1,
                this.BitsPerPixel,
                this.HorizontalResolution,
                this.VerticalResolution / 2);

            int stride = this.Stride;

            ulong[] bitssrc = this.Bits;
            ulong[] bitsdst = dst.Bits;

            int offsrc = 0;
            int offdst = 0;

            for (int i = 0, ii = this.Height >> 1; i < ii; i++, offsrc += 2 * stride, offdst += stride)
            {
                Vectors.Or(stride, bitssrc, offsrc, bitssrc, offsrc + stride, bitsdst, offdst);
            }

            if ((this.Height & 1) != 0)
            {
                Vectors.Copy(stride, bitssrc, offsrc, bitsdst, offdst);
            }

            dst.AppendTransform(new MatrixTransform(1.0, 0.5));
            return(dst);
        }
Exemple #10
0
        public static Bounds BoundToPosition(Vector3 pos, Bounds bounds)
        {
            Vector3 bcenter = Vectors.Copy(bounds.center);
            Vector3 bsize   = Vectors.Copy(bounds.size);

            bcenter.y = pos.y;
            bsize.y   = 30;
            return(new Bounds(bcenter, bsize)); // take size, not ray
        }
Exemple #11
0
        /// <summary>
        /// Creates a new <see cref="Image"/> that is a copy of the current instance.
        /// </summary>
        /// <param name="copyBits">The value indicating whether the <see cref="Image{T}.Bits"/> should be copied to the new <see cref="Image"/>.</param>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public Image Clone(bool copyBits)
        {
            Image dst = new Image(this.Width, this.Height, this);

            if (copyBits)
            {
                Vectors.Copy(this.Bits.Length, this.Bits, 0, dst.Bits, 0);
            }

            return(dst);
        }
Exemple #12
0
            public void Set(int[] classes, int length, int hash, float probBlank, float probNoBlank, State state)
            {
                Vectors.Copy(length, classes, 0, this.Classes, 0);
                this.Length = length;
                this.Hash   = hash;

                this.ProbBlank   = probBlank;
                this.ProbNoBlank = probNoBlank;
                this.Prob        = Mathematics.LogSumExp(probBlank, probNoBlank);

                this.State = state;
            }
Exemple #13
0
        /// <inheritdoc />
        public float Loss(Tensor y, Tensor expected, bool calculateGradient)
        {
            if (y == null)
            {
                throw new ArgumentNullException(nameof(y));
            }

            if (expected == null)
            {
                throw new ArgumentNullException(nameof(expected));
            }

            if (expected.Length != y.Length)
            {
                throw new ArgumentException(string.Format(
                                                CultureInfo.CurrentCulture,
                                                "The number of expected labels: {0} does not match the tensor length: {1}.",
                                                expected.Length,
                                                y.Length));
            }

            float[] yw = y.Weights;
            float[] ew = expected.Weights;

            if (calculateGradient)
            {
                Vectors.Copy(expected.Length, ew, 0, y.Gradient, 0);
            }

            if (y.Shape.Rank == 1)
            {
                return(Calculate(expected.Length, 0, 0));
            }
            else
            {
                int mb     = y.Shape.Axes[0];         // number of items in a mini-batch
                int mbsize = y.Shape.Strides[0];      // item size

                float loss = 0.0f;
                for (int i = 0, yi = 0, ei = 0; i < mb; i++, yi += mbsize, ei += mbsize)
                {
                    loss += Calculate(mbsize, yi, ei);
                }

                return(loss / mb);
            }

            float Calculate(int length, int offy, int offe)
            {
                return(Vectors.EuclideanDistance(length, yw, offy, ew, offe) / length);
            }
        }
Exemple #14
0
        public void ShlTest()
        {
            const int            RepeatCount = 5;
            UlongRandomGenerator random      = new UlongRandomGenerator();

            ulong[] y    = new ulong[3];
            ulong[] copy = new ulong[3];
            int     size = y.Length * 64;

            for (int count = 0; count <= size; count++)
            {
                for (int pos = 0; pos < size - count; pos++)
                {
                    for (int shift = 0; shift <= count; shift++)
                    {
                        for (int i = 0; i < RepeatCount; i++)
                        {
                            random.Generate(y.Length, y);
                            Vectors.Copy(y.Length, y, 0, copy, 0);
                            BitUtils.Shl(count, shift, y, pos);

                            // right part that was not copied
                            if (pos > 0)
                            {
                                Assert.IsTrue(BitUtils.Equals(pos, y, 0, copy, 0));
                            }

                            // shifted part
                            if (shift < count)
                            {
                                Assert.IsTrue(BitUtils.Equals(count - shift, y, pos + shift, copy, pos));
                            }

                            // zeroed part
                            if (shift > 0)
                            {
                                Assert.AreEqual(0, BitUtils.CountOneBits(shift, y, pos));
                            }

                            // left part that was not copied
                            if (pos + count < size)
                            {
                                Assert.IsTrue(BitUtils.Equals(size - (pos + count), y, pos + count, copy, pos + count));
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Computes output of the network.
        /// </summary>
        /// <param name="x">The input tensor.</param>
        /// <returns>
        /// The object that contains the computed results and tensor.
        /// </returns>
        public (IList <IList <(string Answer, float Probability)> > Answers, Tensor Y) Execute(Tensor x)
        {
            const float MaxConfidenceDistance = 0.5f;

            Tensor y = this.Forward(null, x);

            float[] yw         = y.Weights;
            int     mb         = y.Rank == 1 ? 1 : y.Axes[0];
            int     numAnswers = y.Rank == 1 ? y.Length : y.Strides[0];

            List <IList <(string, float)> > answers = new List <IList <(string, float)> >(mb);

            float[] ywmb  = new float[numAnswers];
            int[]   ywidx = new int[numAnswers];
            for (int i = 0, offy = 0; i < mb; i++, offy += numAnswers)
            {
                // copy weights into temporary buffer and sort along with their indexes
                Vectors.Copy(numAnswers, yw, offy, ywmb, 0);
                for (int j = 0; j < numAnswers; j++)
                {
                    ywidx[j] = j;
                }

                Vectors.Sort(numAnswers, ywmb, 0, ywidx, 0, false);

                // create answer for a mini-batch item
                List <(string, float)> mbanswers = new List <(string, float)>(numAnswers);

                float probThreshold = MinMax.Max(ywmb[0] - MaxConfidenceDistance, 0.0f);
                for (int j = 0; j < numAnswers; j++)
                {
                    float prob = ywmb[j];
                    if (prob <= probThreshold)
                    {
                        break;
                    }

                    int    idx = ywidx[j];
                    string cls = this.classes[idx];
                    mbanswers.Add((cls, prob));
                }

                answers.Add(mbanswers);
            }

            return(answers, y);
        }
Exemple #16
0
        /*
         *
         * Options:
         * - ground (water, traps)
         * - recursion
         * - size / depth (puis avant)
         * - other content : Z, animal, torch, lights ...
         *
         */


        public static IEnumerator Rift(EntityPlayer player, Emplacement place, OptionEffect options)
        {
            /*
             * Laisse des blocks tomber au dessus ? just changed  erase="yes"
             * (longueur 1, hauteur (profonfeur), replicats)
             */
            EntityPlayerLocal epl = player as EntityPlayerLocal;

            epl.cameraTransform.SendMessage("ShakeBig");
            yield return(new WaitForSeconds(1f));

            BlockSetter setter    = new BlockSetter(options.OptionBlock);
            Vector3     direction = Vectors.Copy(place.direction);

            direction.y = 0;
            direction   = direction.normalized;

            Vector3i start = Geo3D.Surface(place.ipos);

            for (int k = 0; k < options.OptionShape.shape.z; k++)
            {
                Vector3 kdirection = direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.2f);
                // IntLine traj = new IntLine(start, direction); //east
                IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), kdirection, 0, options.OptionShape.shape.x);
                Vector3i prev    = new Vector3i();
                bool     hasprev = false;
                foreach (Vector3i where in segment)
                {
                    Vector3i Swhere = Geo3D.Surface(where);
                    setter.Apply(Swhere);
                    if (hasprev)
                    {
                        for (int creuse = 1; creuse < options.OptionShape.shape.y; creuse++)
                        {
                            setter.Apply(prev + creuse * Vectors.Down);
                        }
                    }
                    setter.Push();
                    start = Swhere;
                    yield return(new WaitForEndOfFrame());

                    hasprev = true; prev = Swhere;
                }
                yield return(new WaitForSeconds(1f));
            }
        }
Exemple #17
0
        /// <summary>
        /// Creates a scan line filled with pixels of the specified color.
        /// </summary>
        /// <param name="length">The scan line length.</param>
        /// <param name="color">The color to fill the scan line.</param>
        /// <returns>The array that contains the created scan line.</returns>
        private ulong[] ColorScanline(int length, uint color)
        {
            // fill one line with specified color
            uint maxcolor = this.MaxColor;

            color &= maxcolor;

            ulong[] buf = new ulong[length];
            if (color == maxcolor)
            {
                Vectors.Set(length, ulong.MaxValue, buf, 0);
            }
            else if (color != 0)
            {
                if (this.BitsPerPixel == 24)
                {
                    ulong ucolor = (ulong)color | ((ulong)color << 24);
                    buf[0] = ucolor | (ucolor << 48);
                    if (length > 1)
                    {
                        buf[1] = ((ucolor >> 16) & 0x0000_0000_ffff_fffful) | (ucolor << 32);
                    }

                    if (length > 2)
                    {
                        buf[2] = ((ucolor >> 32) & 0x0000_0000_0000_fffful) | (ucolor << 16);
                    }

                    if (length > 3)
                    {
                        for (int yoff = 3, count = 3; yoff < length; count *= 2)
                        {
                            Vectors.Copy(Math.Min(count, length - yoff), buf, 0, buf, yoff);
                            yoff += count;
                        }
                    }
                }
                else
                {
                    // create 64-bit value with each position filled with given color
                    Vectors.Set(length, this.ColorBits(color), buf, 0);
                }
            }

            return(buf);
        }
Exemple #18
0
        /// <summary>
        /// Reduces the height of the <see cref="Image"/> by the factor of 4.
        /// </summary>
        /// <returns>The scaled <see cref="Image"/>.</returns>
        public Image Reduce1x4()
        {
            if (this.BitsPerPixel != 1)
            {
                throw new NotSupportedException(Properties.Resources.E_UnsupportedDepth_1bpp);
            }

            Image dst = new Image(
                this.Width,
                (this.Height + 3) / 4,
                this.BitsPerPixel,
                this.HorizontalResolution,
                this.VerticalResolution / 4);

            int stride = this.Stride;

            ulong[] bitssrc = this.Bits;
            ulong[] bitsdst = dst.Bits;

            int offsrc = 0;
            int offdst = 0;

            for (int i = 0, ii = this.Height / 4; i < ii; i++, offsrc += 4 * stride, offdst += stride)
            {
                Vectors.Or(stride, bitssrc, offsrc, bitssrc, offsrc + stride, bitssrc, offsrc + (2 * stride), bitssrc, offsrc + (3 * stride), bitsdst, offdst);
            }

            switch (this.Height % 4)
            {
            case 1:
                Vectors.Copy(stride, bitssrc, offsrc, bitsdst, offdst);
                break;

            case 2:
                Vectors.Or(stride, bitssrc, offsrc, bitssrc, offsrc + stride, bitsdst, offdst);
                break;

            case 3:
                Vectors.Or(stride, bitssrc, offsrc, bitssrc, offsrc + stride, bitssrc, offsrc + (2 * stride), bitsdst, offdst);
                break;
            }

            dst.AppendTransform(new MatrixTransform(1.0, 0.25));
            return(dst);
        }
Exemple #19
0
        public static IEnumerator Ensure()
        {
            /* Call this and wait for finish whenever prior to using the global ghost */
            EntityPlayerLocal player = GameManager.Instance.World.GetLocalPlayers()[0];
            Bounds            area   = BoundsUtils.BoundsForMinMax(-2, -1, -2, 2, 1, 2);

            while (true)
            {
                Vector3 ppos = Vectors.Copy(player.GetPosition());
                area.center = ppos; // will be surfaced anyway
                pool.Update(area);  // update in any case to invalidate
                if (pool.Entities[0] != null)
                {
                    yield break;
                }
                yield return(Yield);
            }
        }
Exemple #20
0
 private IEnumerator _Search(EntityPlayer player, int cycle=1, int repeat=1) {
     // TODO: check player motion since last reset !
     World World = GameManager.Instance.World;
     for (int k=0; k<cycle; k++) {
         yield return SearchYield;
         _ResetTooFar(player);
         for (int q=0; q<repeat; q++) {
             Searcher.Next();
             if (! Searcher.ok) {Printer.Log(85, "Searcher not ok !", Searcher.x, Searcher.y); yield break;}
             BlockValue existing = World.GetBlock(Searcher.Position);
             if (existing.ischild) continue; // inserts a single will help !
             if (Positions.Count >= maxSize) continue;
             if (Selector != null && !Selector(existing.Block)) continue;
             Vector3i pos = Vectors.Copy(Searcher.Position);
             Printer.Log(85, "Found decoration:", existing.Block, pos, existing);
             Positions.Enqueue(pos);
         }
     }
 }
Exemple #21
0
        public static Tensor Squeeze(this Session session, Tensor x, int axis)
        {
            const string ActionName = "squeeze";

            if (axis < 0)
            {
                throw new ArgumentException(Properties.Resources.E_NegativeAxisIndex, nameof(axis));
            }

            if (x.Rank < 2)
            {
                throw new ArgumentException("The tensor must have the rank of at least 2.", nameof(axis));
            }

            if (x.Axes[axis] != 1)
            {
                throw new ArgumentException("The dimension to remove must be of size 1.", nameof(axis));
            }

            return(session.RunOperation(
                       ActionName,
                       () =>
            {
                bool calculateGradient = session.CalculateGradients && x.CalculateGradient;

                // allocate destination
                Tensor y = session.AllocateTensor(ActionName, x.Shape.RemoveAxis(axis), calculateGradient);

                // simply copy tensor content
                Vectors.Copy(x.Length, x.Weights, 0, y.Weights, 0);

#if !NOLEARNING
                if (calculateGradient)
                {
                    // simply copy tensors
                    session.Push(ActionName, () => x.AddGradient(y.Gradient));
                }
#endif

                return y;
            }));
        }
Exemple #22
0
        /// <summary>
        /// Copies the data from this <see cref="Image"/> to destination <see cref="Image"/>.
        /// </summary>
        /// <param name="dst">The destination <see cref="Image"/>. Can be <b>null</b>.</param>
        /// <param name="copyBits">The value indicating whether the <see cref="Image{T}.Bits"/> should be copied to the new <see cref="Image"/>.</param>
        /// <returns>
        /// The destination <see cref="Image"/>.
        /// </returns>
        /// <remarks>
        /// <para>If <paramref name="dst"/> is <b>null</b> the method creates new destination <see cref="Image"/> with dimensions of this <see cref="Image"/>.</para>
        /// <para>If <paramref name="dst"/> equals this <see cref="Image"/>, the method returns this <see cref="Image"/>.</para>
        /// <para>Conversely, the <paramref name="dst"/> is reallocated to the dimensions of this <see cref="Image"/>.</para>
        /// </remarks>
        public Image Copy(Image dst, bool copyBits)
        {
            if (dst == this)
            {
                return(this);
            }
            else
            {
                // reallocate destination image
                dst = this.CreateTemplate(dst, this.BitsPerPixel);

                // copy bits
                if (copyBits)
                {
                    Vectors.Copy(this.Bits.Length, this.Bits, 0, dst.Bits, 0);
                }

                return(dst);
            }
        }
Exemple #23
0
        /// <inheritdoc />
        public void ComputeDeltas(int epoch, int length, float[] gradient, int totalSamples)
        {
            float learningRate = this.LearningRate;

            if (this.Decay != 0.0f && epoch > 0)
            {
                learningRate /= 1.0f + (this.Decay * epoch);
            }

            float momentum = this.Momentum;

            if (momentum > 0.0f)
            {
                // get accumulator
                float[] velocity = this.accumulators.GetAccumulator(
                    gradient,
                    () => new float[length]);

                if (this.Nesterov)
                {
                    // apply Nesterov momentum
                    // dx = velocity = momentum^2 * velocity - (1 + momentum) * learningRate * g
                    Mathematics.MultiplyAndAdd(gradient.Length, momentum * momentum, velocity, 0, -(1.0f + momentum) * learningRate, gradient, 0);
                    Vectors.Copy(gradient.Length, gradient, 0, velocity, 0);
                }
                else
                {
                    // momentum update
                    // dx = velocity = momentum * velocity - learningRate * g
                    Mathematics.MultiplyAndAdd(gradient.Length, momentum, velocity, 0, -learningRate, gradient, 0);
                    Vectors.Copy(gradient.Length, gradient, 0, velocity, 0);
                }
            }
            else
            {
                // vanilla sgd
                // dx = -learningRate * g
                Mathematics.MulC(gradient.Length, -learningRate, gradient, 0);
            }
        }
Exemple #24
0
        /// <summary>
        /// Packs a collection of dense vectors.
        /// </summary>
        /// <param name="vectors">The dense vectors to pack.</param>
        /// <returns>
        /// The <see cref="DenseVectorPackF"/> object that contains packed dense vectors.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="vectors"/> is <b>null</b>.
        /// </exception>
        public static DenseVectorPackF Pack(IList <IDenseVector <float> > vectors)
        {
            if (vectors == null)
            {
                throw new ArgumentNullException(nameof(vectors));
            }

            if (vectors.Count == 0)
            {
                return(new DenseVectorPackF());
            }

            DenseVectorPackF result = new DenseVectorPackF(vectors.Count, vectors[0].Length);

            float[] x = result.X;
            for (int i = 0, ii = result.Count, len = result.Length, off = 0; i < ii; i++, off += len)
            {
                Vectors.Copy(len, vectors[i].X, vectors[i].Offset, x, off);
            }

            return(result);
        }
Exemple #25
0
        public static Tensor[] Repeat(this Session session, Tensor x, int count)
        {
            const string ActionName = "repeat";

            return(session.RunOperation(
                       ActionName,
                       () =>
            {
                bool calculateGradient = session.CalculateGradients && x.CalculateGradient;

                Tensor[] ys = session.AllocateTensors(ActionName, count, x.Shape, calculateGradient);
                for (int i = 0; i < count; i++)
                {
                    Vectors.Copy(x.Length, x.Weights, 0, ys[i].Weights, 0);
                }

#if !NOLEARNING
                if (calculateGradient)
                {
                    session.Push(
                        ActionName,
                        () =>
                    {
                        float alpha = 1.0f / count;
                        for (int i = 0; i < count; i++)
                        {
                            Mathematics.AddProductC(x.Length, ys[i].Gradient, 0, alpha, x.Gradient, 0);
                        }
                    });

                    // return copy of the array; calling method can replace its content; our closure keeps the array, not its items
                    return ys.ToArray();
                }
#endif

                return ys;
            }));
        }
Exemple #26
0
        private static void Untile(Tensor x, int axis, int count, Tensor y, bool useGradients)
        {
            int ylen    = y.Length;
            int ystride = axis == 0 ? ylen : y.Strides[axis - 1];

            float[] xw = useGradients ? x.Gradient : x.Weights;
            float[] yw = useGradients ? y.Gradient : y.Weights;

            for (int offx = 0, offy = 0; offy < ylen; offy += ystride)
            {
                for (int i = 0; i < count; i++, offx += ystride)
                {
                    if (useGradients || i > 0)
                    {
                        Mathematics.Add(ystride, xw, offx, yw, offy);
                    }
                    else
                    {
                        Vectors.Copy(ystride, xw, offx, yw, offy);
                    }
                }
            }
        }
Exemple #27
0
        public static Tensor Copy(this Session session, Tensor x)
        {
            const string ActionName = "copy";

            return(session.RunOperation(
                       ActionName,
                       () =>
            {
                bool calculateGradient = session.CalculateGradients && x.CalculateGradient;

                Tensor y = session.AllocateTensor(ActionName, x.Shape, calculateGradient);
                Vectors.Copy(x.Length, x.Weights, 0, y.Weights, 0);

#if !NOLEARNING
                if (calculateGradient)
                {
                    session.Push(ActionName, () => x.AddGradient(y.Gradient));
                }
#endif

                return y;
            }));
        }
Exemple #28
0
        /// <summary>
        /// Calculates the histogram of oriented gradients (HOG) on the <see cref="Image"/>.
        /// </summary>
        /// <param name="cellSize">The cell size, in pixels.</param>
        /// <param name="blockSize">The block size, in number of <paramref name="cellSize"/>.</param>
        /// <param name="blockStride">The block stride size, in number of <paramref name="cellSize"/>.</param>
        /// <param name="numberOfBins">The number of bins (orientations) in the histogram.</param>
        /// <param name="threshold">
        /// The threshold value to apply after normalization.
        /// Bins that are less than the threshold, are set to zero.
        /// </param>
        /// <returns>
        /// The <see cref="DenseVectorPackF"/> that contains packed points of interest.
        /// </returns>
        /// <exception cref="NotSupportedException">
        /// The <see cref="Image{T}.BitsPerPixel"/> is not 1, 8, 24, or 32.
        /// </exception>
        public DenseVectorPackF HOG(
            int cellSize,
            int blockSize,
            int blockStride,
            int numberOfBins,
            float threshold)
        {
            // convert image to float
            ImageF srcf   = PrepareImage();
            int    width  = srcf.Width;
            int    height = srcf.Height;
            int    stride = srcf.Stride;

            float[] bits = srcf.Bits;

            /*if (NativeMethods.hog(
             *  srcf.BitsPerPixel,
             *  srcf.Width,
             *  srcf.Height,
             *  srcf.Stride,
             *  srcf.Bits) != 0)
             * {
             *  throw new OutOfMemoryException();
             * }*/

            // calculate gradient vectors magnitude and direction using Prewitt operator (-1 0 1)
            float[] mag = new float[bits.Length];
            float[] ang = new float[bits.Length];
            NativeMethods.gradientVectorPrewitt_f32(width, height, bits, stride, mag, stride, ang, stride);

            // convert angles to bins
            Mathematics.DivC(ang.Length, (float)(Math.PI / numberOfBins), ang, 0);
            Vectors.Abs(ang.Length, ang, 0);

            // calculate histograms
            int cellCountX = width / cellSize;
            int cellCountY = height / cellSize;

            int blockCountX     = ComputeBlockCount(cellCountX);
            int blockCountY     = ComputeBlockCount(cellCountY);
            int blockCount      = blockCountX * blockCountY;
            int blockSizeInBins = blockSize * blockSize * numberOfBins;

            float[] blocks   = new float[blockCount * blockSizeInBins];
            int     offblock = 0; // running block offset

            // to save memory we allocate histograms needed for one row of blocks only
            // when we move throw the rows, the first histogram (not needed anymore) becomes last (working)
            List <float[]> hist = CreateRotatingHist();

            for (int iy = 0, offy = 0; iy < cellCountY; iy++, offy += stride * cellSize)
            {
                float[] h = hist[Core.MinMax.Min(iy, blockSize - 1)];
                ComputeHistLine(offy, h);

                if (iy + 1 >= blockSize)
                {
                    // calculate blocks - we are at the last block line
                    if (((iy + 1 - blockSize) % blockStride) == 0)
                    {
                        ComputeBlockLine();
                    }

                    // rotate histograms
                    if (blockSize > 1 && iy + 1 < cellCountY)
                    {
                        RotateHist(hist);
                    }
                }
            }

            Debug.Assert(offblock == blocks.Length, "We must have processed all blocks by now.");

            // normalize blocks
            const float Eps = 1e-10f;

            for (int i = 0, off = 0; i < blockCount; i++, off += blockSizeInBins)
            {
                float norm = Vectors.L2Norm(blockSizeInBins, blocks, off);
                Mathematics.DivC(blockSizeInBins, norm + Eps, blocks, off);
            }

            // apply threshold
            if (threshold > 0.0f)
            {
                Vectors.ThresholdLT(blocks.Length, threshold, 0.0f, blocks, 0);
            }

            /*DenseVectorProxyF[] dense = new DenseVectorProxyF[blockCount];
             * for (int i = 0, off = 0; i < blockCount; i++, off += blockSizeInBins)
             * {
             *  dense[i] = new DenseVectorProxyF(blockSizeInBins, blocks, off);
             * }*/

            /*SparseVectorF[] sparse = new SparseVectorF[blockCount];
             * for (int i = 0; i < blockCount; i++)
             * {
             *  sparse[i] = SparseVectorF.FromDense(blockSizeInBins, vectors[i].X, 0);
             * }*/

            return(new DenseVectorPackF(blockCount, blockSizeInBins, blocks));

            ImageF PrepareImage()
            {
                // convert image to 8bpp, then float
                return(this
                       .ConvertTo(null, 8)
                       .Convert8To32f(
                           ComputeImageSize(this.Width),
                           ComputeImageSize(this.Height),
                           BorderType.BorderRepl,
                           0));

                int ComputeImageSize(int size)
                {
                    int kernelSize   = cellSize * blockSize;
                    int kernelStride = cellSize * blockStride;

                    return(Core.MinMax.Max(size - kernelSize, 0).RoundUp(kernelStride) + kernelSize);
                }
            }

            int ComputeBlockCount(int cellCount)
            {
                return((Core.MinMax.Max(cellCount - blockSize, 0) / blockStride) + 1);
            }

            List <float[]> CreateRotatingHist()
            {
                List <float[]> h = new List <float[]>(blockSize);

                for (int i = 0; i < blockSize; i++)
                {
                    h.Add(new float[cellCountX * numberOfBins]);
                }

                return(h);
            }

            void RotateHist(List <float[]> h)
            {
                float[] temp = h[0];
                h.RemoveAt(0);
                h.Add(temp);
                Vectors.Set(temp.Length, 0, temp, 0);
            }

            void ComputeHistLine(int offy, float[] h)
            {
                for (int ix = 0, offx = offy, offh = 0; ix < cellCountX; ix++, offx += cellSize, offh += numberOfBins)
                {
                    for (int iyc = 0, offyc = offx; iyc < cellSize; iyc++, offyc += stride)
                    {
                        for (int ixc = 0, offxc = offyc; ixc < cellSize; ixc++, offxc++)
                        {
                            float value = mag[offxc];
                            if (value != 0.0f)
                            {
                                ////int bin = (int)ang[offxc] % numberOfBins;
                                ////h[offh + bin] += mag[offxc];

                                float angle = ang[offxc];

                                int   bin    = (int)angle;
                                float value1 = value * (angle - bin);

                                h[offh + (bin % numberOfBins)]       += value1;
                                h[offh + ((bin + 1) % numberOfBins)] += value - value1;
                            }
                        }
                    }
                }
            }

            void ComputeBlockLine()
            {
                int blockLengthInBins = blockSize * numberOfBins;
                int blockStrideInBins = blockStride * numberOfBins;

                for (int ix = 0, offh = 0; ix < blockCountX; ix++, offh += blockStrideInBins)
                {
                    for (int iyc = 0; iyc < blockSize; iyc++)
                    {
                        Vectors.Copy(blockLengthInBins, hist[iyc], offh, blocks, offblock);
                        offblock += blockLengthInBins;
                    }
                }
            }
        }
Exemple #29
0
        public bool Optimize(
            int numberOfVariables,
            float[] c,
            float[] p,
            int[] y,
            Func <int, int[], int, float[], float[]> q,
            out float[] solution,
            out float rho)
        {
            // make copies, these array will be modified
            p = p.ToArray();
            y = y.ToArray();

            float[] temp = new float[numberOfVariables];

            float[] g    = new float[numberOfVariables];   // gradient
            float[] gbar = new float[numberOfVariables];   // gradient, if we treat free variables as 0

            float[] qd = new float[numberOfVariables];
            for (int k = 0; k < qd.Length; k++)
            {
                qd[k] = q(k, new[] { k }, 1, temp)[0];
            }

            float[] qi = new float[numberOfVariables];
            float[] qj = new float[numberOfVariables];

            bool unshrink = false;

            // Lagrange multipliers
            float[] alpha = new float[numberOfVariables];

            // initialize alpha_status
            Status[] alphaStatus = new Status[numberOfVariables];
            for (int i = 0; i < numberOfVariables; i++)
            {
                UpdateAlphaStatus(i);
            }

            // initialize active set (for shrinking)
            int activeSize = numberOfVariables;

            int[] activeSet = Arrays.Indexes(numberOfVariables);

            // initialize index lookup vector
            int[] indices = Arrays.Indexes(numberOfVariables);

            // initialize gradient
            Vectors.Copy(numberOfVariables, p, 0, g, 0);
            Vectors.Set(numberOfVariables, 0.0f, gbar, 0);

            /*for (int i = 0; i < numberOfVariables; i++)
             * {
             *  g[i] = p[i];
             *  gbar[i] = 0;
             * }*/

            for (int i = 0; i < numberOfVariables; i++)
            {
                if (!IsLowerBound(i))
                {
                    q(i, indices, numberOfVariables, qi);

                    Mathematics.AddProductC(numberOfVariables, qi, 0, alpha[i], g, 0);

                    /*float alpha_i = alpha[i];
                     * for (int j = 0; j < numberOfVariables; j++)
                     * {
                     *  g[j] += alpha_i * qi[j];
                     * }*/

                    if (IsUpperBound(i))
                    {
                        Mathematics.AddProductC(numberOfVariables, qi, 0, c[i], gbar, 0);

                        /*for (int j = 0; j < numberOfVariables; j++)
                         * {
                         *  gbar[j] += c[i] * qi[j];
                         * }*/
                    }
                }
            }

            // optimization step
            int iter     = 0;
            int max_iter = MinMax.Max(10000000, numberOfVariables > int.MaxValue / 100 ? int.MaxValue : 100 * numberOfVariables);
            int counter  = MinMax.Min(numberOfVariables, 1000) + 1;

            while (iter < max_iter)
            {
                // show progress and do shrinking
                if (--counter == 0)
                {
                    counter = MinMax.Min(numberOfVariables, 1000);
                    if (this.Shrinking)
                    {
                        Shrink();
                    }

                    Trace.WriteLine(".");
                }

                if (SelectWorkingSet(out int i, out int j) != 0)
                {
                    // reconstruct the whole gradient
                    ReconstructGradient();

                    // reset active set size and check
                    activeSize = numberOfVariables;
                    Trace.WriteLine("*");

                    if (SelectWorkingSet(out i, out j) != 0)
                    {
                        break;
                    }
                    else
                    {
                        counter = 1;    // do shrinking next iteration
                    }
                }

                iter++;

                // update alpha[i] and alpha[j], handle bounds carefully
                q(i, indices, activeSize, qi);
                q(j, indices, activeSize, qj);

                float ci = c[i];
                float cj = c[j];

                float old_alpha_i = alpha[i];
                float old_alpha_j = alpha[j];

                if (y[i] != y[j])
                {
                    float quad_coef = qd[i] + qd[j] + (2.0f * qi[j]);
                    if (quad_coef <= 0)
                    {
                        quad_coef = TAU;
                    }

                    float delta = (-g[i] - g[j]) / quad_coef;
                    float diff  = alpha[i] - alpha[j];
                    alpha[i] += delta;
                    alpha[j] += delta;

                    if (diff > 0)
                    {
                        if (alpha[j] < 0)
                        {
                            alpha[j] = 0;
                            alpha[i] = diff;
                        }
                    }
                    else
                    {
                        if (alpha[i] < 0)
                        {
                            alpha[i] = 0;
                            alpha[j] = -diff;
                        }
                    }

                    if (diff > ci - cj)
                    {
                        if (alpha[i] > ci)
                        {
                            alpha[i] = ci;
                            alpha[j] = ci - diff;
                        }
                    }
                    else
                    {
                        if (alpha[j] > cj)
                        {
                            alpha[j] = cj;
                            alpha[i] = cj + diff;
                        }
                    }
                }
                else
                {
                    float quad_coef = qd[i] + qd[j] - (2.0f * qi[j]);
                    if (quad_coef <= 0)
                    {
                        quad_coef = TAU;
                    }

                    float delta = (g[i] - g[j]) / quad_coef;
                    float sum   = alpha[i] + alpha[j];
                    alpha[i] -= delta;
                    alpha[j] += delta;

                    if (sum > ci)
                    {
                        if (alpha[i] > ci)
                        {
                            alpha[i] = ci;
                            alpha[j] = sum - ci;
                        }
                    }
                    else
                    {
                        if (alpha[j] < 0)
                        {
                            alpha[j] = 0;
                            alpha[i] = sum;
                        }
                    }

                    if (sum > cj)
                    {
                        if (alpha[j] > cj)
                        {
                            alpha[j] = cj;
                            alpha[i] = sum - cj;
                        }
                    }
                    else
                    {
                        if (alpha[i] < 0)
                        {
                            alpha[i] = 0;
                            alpha[j] = sum;
                        }
                    }
                }

                // update G
                float delta_alpha_i = alpha[i] - old_alpha_i;
                float delta_alpha_j = alpha[j] - old_alpha_j;

                for (int k = 0; k < activeSize; k++)
                {
                    g[k] += (qi[k] * delta_alpha_i) + (qj[k] * delta_alpha_j);
                }

                // update alpha_status and G_bar
                {
                    bool ui = IsUpperBound(i);
                    bool uj = IsUpperBound(j);
                    UpdateAlphaStatus(i);
                    UpdateAlphaStatus(j);

                    if (ui != IsUpperBound(i))
                    {
                        q(i, indices, numberOfVariables, qi);
                        Mathematics.AddProductC(numberOfVariables, qi, 0, ui ? -ci : ci, gbar, 0);

                        /*if (ui)
                         * {
                         *  for (int k = 0; k < numberOfVariables; k++)
                         *  {
                         *      gbar[k] -= ci * qi[k];
                         *  }
                         * }
                         * else
                         * {
                         *  for (int k = 0; k < numberOfVariables; k++)
                         *  {
                         *      gbar[k] += ci * qi[k];
                         *  }
                         * }*/
                    }

                    if (uj != IsUpperBound(j))
                    {
                        q(j, indices, numberOfVariables, qj);
                        Mathematics.AddProductC(numberOfVariables, qj, 0, uj ? -cj : cj, gbar, 0);

                        /*if (uj)
                         * {
                         *  for (int k = 0; k < numberOfVariables; k++)
                         *  {
                         *      gbar[k] -= cj * qj[k];
                         *  }
                         * }
                         * else
                         * {
                         *  for (int k = 0; k < numberOfVariables; k++)
                         *  {
                         *      gbar[k] += cj * qj[k];
                         *  }
                         * }*/
                    }
                }
            }

            if (iter >= max_iter)
            {
                if (activeSize < numberOfVariables)
                {
                    // reconstruct the whole gradient to calculate objective value
                    ReconstructGradient();
                    activeSize = numberOfVariables;
                    Trace.WriteLine("*");
                }

                Trace.WriteLine("WARNING: reaching max number of iterations.");
            }

            // calculate rho
            rho = CalculateRho();

            // calculate objective value

            /*float v = 0;
             * for (int i = 0; i < numberOfVariables; i++)
             * {
             *  v += alpha[i] * (g[i] + p[i]);
             * }
             *
             * si->obj = v / 2;*/

            // put back the solution
            solution = new float[numberOfVariables];
            for (int i = 0; i < numberOfVariables; i++)
            {
                solution[activeSet[i]] = alpha[i];
            }

            ////si->upper_bound_p = Cp;
            ////si->upper_bound_n = Cn;

            Trace.WriteLine(string.Format(
                                CultureInfo.InvariantCulture,
                                "optimization finished, #iter = {0}",
                                iter));

            return(iter < max_iter);

            // return 1 if already optimal, return 0 otherwise
            int SelectWorkingSet(out int out_i, out int out_j)
            {
                // return i,j such that
                // i: maximizes -y_i * grad(f)_i, i in I_up(\alpha)
                // j: minimizes the decrease of obj value
                //    (if quadratic coefficient <= 0, replace it with tau)
                //    -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha)
                float gmax         = float.NegativeInfinity;
                float gmax2        = float.NegativeInfinity;
                int   gmax_idx     = -1;
                int   gmin_idx     = -1;
                float obj_diff_min = float.PositiveInfinity;

                for (int t = 0; t < activeSize; t++)
                {
                    if (y[t] == +1)
                    {
                        if (!IsUpperBound(t))
                        {
                            if (-g[t] >= gmax)
                            {
                                gmax     = -g[t];
                                gmax_idx = t;
                            }
                        }
                    }
                    else
                    {
                        if (!IsLowerBound(t))
                        {
                            if (g[t] >= gmax)
                            {
                                gmax     = g[t];
                                gmax_idx = t;
                            }
                        }
                    }
                }

                int i = gmax_idx;

                if (i != -1)
                {
                    q(i, indices, activeSize, temp); // NULL Q_i not accessed: Gmax=-INF if i=-1
                }

                for (int j = 0; j < activeSize; j++)
                {
                    if (y[j] == +1)
                    {
                        if (!IsLowerBound(j))
                        {
                            float grad_diff = gmax + g[j];
                            if (g[j] >= gmax2)
                            {
                                gmax2 = g[j];
                            }

                            if (grad_diff > 0)
                            {
                                float obj_diff;
                                float quad_coef = qd[i] + qd[j] - (2.0f * y[i] * temp[j]);

                                if (quad_coef > 0)
                                {
                                    obj_diff = -(grad_diff * grad_diff) / quad_coef;
                                }
                                else
                                {
                                    obj_diff = -(grad_diff * grad_diff) / TAU;
                                }

                                if (obj_diff <= obj_diff_min)
                                {
                                    gmin_idx     = j;
                                    obj_diff_min = obj_diff;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (!IsUpperBound(j))
                        {
                            float grad_diff = gmax - g[j];
                            if (-g[j] >= gmax2)
                            {
                                gmax2 = -g[j];
                            }

                            if (grad_diff > 0)
                            {
                                float obj_diff;
                                float quad_coef = qd[i] + qd[j] + (2.0f * y[i] * temp[j]);

                                if (quad_coef > 0)
                                {
                                    obj_diff = -(grad_diff * grad_diff) / quad_coef;
                                }
                                else
                                {
                                    obj_diff = -(grad_diff * grad_diff) / TAU;
                                }

                                if (obj_diff <= obj_diff_min)
                                {
                                    gmin_idx     = j;
                                    obj_diff_min = obj_diff;
                                }
                            }
                        }
                    }
                }

                if (gmax + gmax2 < this.Tolerance)
                {
                    out_i = 0;
                    out_j = 0;
                    return(1);
                }

                out_i = gmax_idx;
                out_j = gmin_idx;
                return(0);
            }

            void Shrink()
            {
                float gmax1 = float.NegativeInfinity;   // max { -y_i * grad(f)_i | i in I_up(\alpha) }
                float gmax2 = float.NegativeInfinity;   // max { y_i * grad(f)_i | i in I_low(\alpha) }

                // find maximal violating pair first
                for (int i = 0; i < activeSize; i++)
                {
                    if (y[i] == 1)
                    {
                        if (!IsUpperBound(i))
                        {
                            if (-g[i] >= gmax1)
                            {
                                gmax1 = -g[i];
                            }
                        }

                        if (!IsLowerBound(i))
                        {
                            if (g[i] >= gmax2)
                            {
                                gmax2 = g[i];
                            }
                        }
                    }
                    else
                    {
                        if (!IsUpperBound(i))
                        {
                            if (-g[i] >= gmax2)
                            {
                                gmax2 = -g[i];
                            }
                        }

                        if (!IsLowerBound(i))
                        {
                            if (g[i] >= gmax1)
                            {
                                gmax1 = g[i];
                            }
                        }
                    }
                }

                if (!unshrink && gmax1 + gmax2 <= this.Tolerance * 10)
                {
                    unshrink = true;
                    ReconstructGradient();
                    activeSize = numberOfVariables;

                    Trace.WriteLine("*");
                }

                for (int i = 0; i < activeSize; i++)
                {
                    if (IsShrunk(i, gmax1, gmax2))
                    {
                        activeSize--;
                        while (activeSize > i)
                        {
                            if (!IsShrunk(activeSize, gmax1, gmax2))
                            {
                                SwapIndex(i, activeSize);
                                break;
                            }

                            activeSize--;
                        }
                    }
                }
            }

            void ReconstructGradient()
            {
                // reconstruct inactive elements of G from G_bar and free variables
                if (activeSize == numberOfVariables)
                {
                    return;
                }

                Mathematics.Add(
                    numberOfVariables - activeSize,
                    gbar,
                    activeSize,
                    p,
                    activeSize,
                    g,
                    activeSize);

                /*for (int j = activeSize; j < numberOfVariables; j++)
                 * {
                 *  g[j] = gbar[j] + p[j];
                 * }*/

                int freeCount = 0;

                for (int j = 0; j < activeSize; j++)
                {
                    if (IsFree(j))
                    {
                        freeCount++;
                    }
                }

                if (2 * freeCount < activeSize)
                {
                    Trace.WriteLine("WARNING: using -h 0 may be faster");
                }

                if (freeCount * numberOfVariables > 2 * activeSize * (numberOfVariables - activeSize))
                {
                    for (int i = activeSize; i < numberOfVariables; i++)
                    {
                        q(indices[i], indices, activeSize, temp);

                        for (int j = 0; j < activeSize; j++)
                        {
                            if (IsFree(j))
                            {
                                g[i] += alpha[j] * temp[j];
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < activeSize; i++)
                    {
                        if (IsFree(i))
                        {
                            q(indices[i], indices, numberOfVariables, temp);

                            Mathematics.AddProductC(
                                numberOfVariables - activeSize,
                                temp,
                                activeSize,
                                alpha[i],
                                g,
                                activeSize);

                            /*float alpha_i = alpha[i];
                             * for (int j = activeSize; j < numberOfVariables; j++)
                             * {
                             *  g[j] += alpha_i * temp[j];
                             * }*/
                        }
                    }
                }
            }

            void SwapIndex(int i, int j)
            {
                Swap(indices);
                Swap(y);
                Swap(g);
                Swap(alphaStatus);
                Swap(alpha);
                Swap(p);
                Swap(activeSet);
                Swap(gbar);

                void Swap <T>(T[] array)
                {
                    T t = array[i];

                    array[i] = array[j];
                    array[j] = t;
                }
            }
Exemple #30
0
        public void DrawRectangle(int x, int y, int width, int height, uint color)
        {
            this.ValidateArea(x, y, width, height);

            if (width == 0 || height == 0)
            {
                // nothing to draw
                return;
            }

            ulong[] bits         = this.Bits;
            int     bitsPerPixel = this.BitsPerPixel;

            if (bitsPerPixel == 24)
            {
                ulong[] colors  = this.ColorScanline(Image.CalculateStride(width, 24), color);
                int     stride8 = this.Stride8;

                unsafe
                {
                    fixed(ulong *ubits = &bits[y * this.Stride], ucolors = colors)
                    {
                        byte *ptrcolors = (byte *)ucolors;
                        byte *ptrbits   = (byte *)ubits + (x * 3);

                        // draw top
                        Vectors.Copy(width * 3, ptrcolors, ptrbits);
                        ptrbits += stride8;

                        // draw left and right
                        for (int i = 1, ii = height - 1; i < ii; i++, ptrbits += stride8)
                        {
                            Vectors.Copy(3, ptrcolors, ptrbits);
                            Vectors.Copy(3, ptrcolors, ptrbits + (width * 3));
                        }

                        // draw bottom
                        Vectors.Copy(width * 3, ptrcolors, ptrbits);
                    }
                }
            }
            else
            {
                int   stride1   = this.Stride1;
                ulong colorbits = this.ColorBits(color);

                // draw top
                int pos = (y * stride1) + (x * bitsPerPixel);
                BitUtils.SetBits(width * bitsPerPixel, colorbits, bits, pos);
                pos += stride1;

                // draw left and right
                int posend = pos + (width * bitsPerPixel);
                for (int i = 1, ii = height - 1; i < ii; i++, pos += stride1, posend += stride1)
                {
                    BitUtils.SetBits(bitsPerPixel, colorbits, bits, pos);
                    BitUtils.SetBits(bitsPerPixel, colorbits, bits, posend);
                }

                // draw bottom
                BitUtils.SetBits(width * bitsPerPixel, colorbits, bits, pos);
            }
        }