public float Interpolate(float x, float y)
        {
            int   xi = BinaryMath.BinarySearchClosest <float>(x, X);
            float x1 = X[xi - 1];
            float x2 = X[xi];
            float y1 = Y[xi - 1];
            float y2 = Y[xi];

            return(((x - x1) / (x2 - x1)) * (y2 - y1) + y1);
        }
Ejemplo n.º 2
0
        /// <summary>Constructs a new instance of the <see cref="MaximumLengthSequence"/> class with a minimum length given by the argument.</summary>
        /// <param name="sequenceLength">The minimum length of the binary sequency. If the provided value is not a number (2^k-1), the value will be rounded up to the next possible sequence length.</param>
        /// <returns>The constructed instance of the <see cref="MaximumLengthSequence"/> class with the given minimum sequence length.</returns>
        public static MaximumLengthSequence FromMinimumSequenceLength(ulong sequenceLength)
        {
            if (sequenceLength < MinimumSequenceLength)
            {
                sequenceLength = MinimumSequenceLength;
            }
            int stages = 1 + BinaryMath.Ld(sequenceLength);

            return(FromNumberOfStages(stages));
        }
        public float Interpolate(Tx x)
        {
            int i = BinaryMath.BinarySearchClosest <Tx>(x, X);

            /*float x1 = X[i - 1];
             * float x2 = X[i];
             * float y1 = Y[i - 1];
             * float y2 = Y[i];
             * return ((x - x1) / (x2 - x1)) * (y2 - y1) + y1;*/
            return(0);
        }
Ejemplo n.º 4
0
        public void TestIsPowerOfTwoOrZero()
        {
            // 32 bit, signed
            Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero(0));
            for (int i = 0; i < 32; ++i)
            {
                uint x = 1u << i;
                Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero((int)x));
                if (i > 0)
                {
                    x += x - 1;
                    Assert.AreEqual(false, BinaryMath.IsPowerOfTwoOrZero((int)x));
                }
            }

            // 32 bit, unsigned
            Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero((uint)0));
            for (int i = 0; i < 32; ++i)
            {
                uint x = 1u << i;
                Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero(x));
                if (i > 0)
                {
                    x += x - 1;
                    Assert.AreEqual(false, BinaryMath.IsPowerOfTwoOrZero(x));
                }
            }

            // 64 bit, signed
            Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero((long)0));
            for (int i = 0; i < 64; ++i)
            {
                ulong x = 1ul << i;
                Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero((long)x));
                if (i > 0)
                {
                    x += x - 1;
                    Assert.AreEqual(false, BinaryMath.IsPowerOfTwoOrZero((long)x));
                }
            }

            // 64 bit, unsigned
            Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero((ulong)0));
            for (int i = 0; i < 64; ++i)
            {
                ulong x = 1ul << i;
                Assert.AreEqual(true, BinaryMath.IsPowerOfTwoOrZero(x));
                if (i > 0)
                {
                    x += x - 1;
                    Assert.AreEqual(false, BinaryMath.IsPowerOfTwoOrZero(x));
                }
            }
        }
Ejemplo n.º 5
0
        public void TestLd64()
        {
            Assert.AreEqual(int.MinValue, BinaryMath.Ld(0u));

            for (int i = 0; i < 64; ++i)
            {
                ulong x = 1ul << i;
                Assert.AreEqual(i, BinaryMath.Ld(x));
                x += x - 1;
                Assert.AreEqual(i, BinaryMath.Ld(x));
            }
        }
Ejemplo n.º 6
0
        public void TestLd32()
        {
            Assert.AreEqual(int.MinValue, BinaryMath.Ld(0u));

            for (int i = 0; i < 32; ++i)
            {
                uint x = 1u << i;
                Assert.AreEqual(i, BinaryMath.Ld(x));
                x += x - 1;
                Assert.AreEqual(i, BinaryMath.Ld(x));
            }
        }
Ejemplo n.º 7
0
        /// <summary>Gets the next possible sequence length that is equal to or greater than the provided <paramref name="sequenceLength"/>.</summary>
        /// <param name="sequenceLength">The minimum length of the binary sequency. </param>
        /// <returns>Next possible sequence length that is equal to or greater than the provided <paramref name="sequenceLength"/>.</returns>
        public static ulong GetSequenceLengthFromMinimumSequenceLength(ulong sequenceLength)
        {
            var result = sequenceLength;

            if (!(sequenceLength >= MinimumSequenceLength))
            {
                result = MinimumSequenceLength;
            }

            int stages = 1 + BinaryMath.Ld(sequenceLength);

            return(GetSequenceLengthFromNumberOfStages(stages));
        }
Ejemplo n.º 8
0
        public void TestParityOfULong()
        {
            Assert.AreEqual(false, BinaryMath.IsParityOdd(0x0000000000000000ul));
            Assert.AreEqual(false, BinaryMath.IsParityOdd(0xFFFFFFFFFFFFFFFFul));
            Assert.AreEqual(false, BinaryMath.IsParityOdd(0x8000000000000001ul));
            Assert.AreEqual(false, BinaryMath.IsParityOdd(0x1000000000000008ul));
            Assert.AreEqual(false, BinaryMath.IsParityOdd(0x2000000000000002ul));

            Assert.AreEqual(true, BinaryMath.IsParityOdd(0x0000000000000001ul));
            Assert.AreEqual(true, BinaryMath.IsParityOdd(0x1000000000000000ul));
            Assert.AreEqual(true, BinaryMath.IsParityOdd(0x8000000000000000ul));
            Assert.AreEqual(true, BinaryMath.IsParityOdd(0x0000000000000008ul));
        }
Ejemplo n.º 9
0
        public void TestParityOfUShort()
        {
            Assert.AreEqual(false, BinaryMath.IsParityOdd((ushort)0x0000));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((ushort)0xFFFF));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((ushort)0x8001));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((ushort)0x1008));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((ushort)0x2002));

            Assert.AreEqual(true, BinaryMath.IsParityOdd((ushort)0x0001));
            Assert.AreEqual(true, BinaryMath.IsParityOdd((ushort)0x1000));
            Assert.AreEqual(true, BinaryMath.IsParityOdd((ushort)0x8000));
            Assert.AreEqual(true, BinaryMath.IsParityOdd((ushort)0x0008));
        }
Ejemplo n.º 10
0
        public void TestParityOfByte()
        {
            Assert.AreEqual(false, BinaryMath.IsParityOdd((byte)0x00));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((byte)0xFF));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((byte)0x81));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((byte)0x18));
            Assert.AreEqual(false, BinaryMath.IsParityOdd((byte)0x22));

            Assert.AreEqual(true, BinaryMath.IsParityOdd((byte)0x01));
            Assert.AreEqual(true, BinaryMath.IsParityOdd((byte)0x10));
            Assert.AreEqual(true, BinaryMath.IsParityOdd((byte)0x80));
            Assert.AreEqual(true, BinaryMath.IsParityOdd((byte)0x08));
        }
Ejemplo n.º 11
0
        public void TestNextPowerOfTwoGreaterOrEqual()
        {
            // 32 bit, signed
            Assert.AreEqual(1, BinaryMath.NextPowerOfTwoGreaterOrEqualThan(0));
            for (int i = 0; i < 31; ++i)
            {
                uint x = 1u << i;
                Assert.AreEqual(x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((int)x));
                if (i < 30)
                {
                    Assert.AreEqual(x + x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((int)(x + 1)));
                }
            }

            // 32 bit, unsigned
            Assert.AreEqual(1, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((uint)0));
            for (int i = 0; i < 32; ++i)
            {
                uint x = 1u << i;
                Assert.AreEqual(x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan(x));
                if (i < 31)
                {
                    Assert.AreEqual(x + x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan(x + 1));
                }
            }

            // 64 bit, signed
            Assert.AreEqual(1, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((long)0));
            for (int i = 0; i < 63; ++i)
            {
                ulong x = 1ul << i;
                Assert.AreEqual(x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((long)x));
                if (i < 62)
                {
                    Assert.AreEqual(x + x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((long)(x + 1)));
                }
            }

            // 64 bit, unsigned
            Assert.AreEqual(1, BinaryMath.NextPowerOfTwoGreaterOrEqualThan((ulong)0));
            for (int i = 0; i < 64; ++i)
            {
                ulong x = 1UL << i;
                Assert.AreEqual(x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan(x));
                if (i < 63)
                {
                    Assert.AreEqual(x + x, BinaryMath.NextPowerOfTwoGreaterOrEqualThan(x + 1));
                }
            }
        }
Ejemplo n.º 12
0
 public void AddSlice(RegionOfInterestSlice slice, double coordinate)
 {
     if (!sliceDictionary.ContainsKey(coordinate))
     {
         // Add the ROIs to arrays but ensure they are sorted by z coord
         int insertIndex = BinaryMath.BinarySearchClosest(coordinate, roiZCoordinates);
         if (insertIndex < 0)
         {
             insertIndex = ~insertIndex;
         }
         RegionOfInterestSlices.Insert(insertIndex, slice);
         roiZCoordinates.Insert(insertIndex, coordinate);
         sliceDictionary.Add(coordinate, slice);
     }
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Interpolates between two binary masks.
        /// See Schenk et. al Efficient Semiautomatic Segmentation of 3D objects in Medical Images
        /// Note this DOES NOT CURRENTLY WORK. Needs tweaking
        /// </summary>
        /// <param name="mask2"></param>
        /// <param name="frac">0 is all this mask, 1 is all mask 2</param>
        /// <returns></returns>
        public BinaryMask InterpolateWith(BinaryMask mask2, double frac)
        {
            BinaryMask newMask = new BinaryMask(XRange, YRange);

            float[] m1distance = BinaryMath.DistanceTransform(InsideBinaryData);
            float[] m2distance = BinaryMath.DistanceTransform(mask2.InsideBinaryData);
            newMask.InsideBinaryData = new bool[InsideBinaryData.Length];

            for (int i = 0; i < m1distance.Length; i++)
            {
                var dist = m1distance[i] * (1 - frac) + m2distance[i] * (frac);
                if (dist <= 0)
                {
                    newMask.InsideBinaryData[i] = true;
                }
            }
            return(newMask);
        }
Ejemplo n.º 14
0
        /// <summary>Initializes a new instance of the <see cref="FastHadamardTransformation"/> class.</summary>
        /// <param name="mls">The maximum length sequence that is used to generate the input signal for the device under test (DUT).</param>
        public FastHadamardTransformation(Calc.Probability.MaximumLengthSequence mls)
        {
            _responsePermutation = new int[mls.Length];
            _signalPermutation   = new int[mls.Length];
            _permutedSignal      = new double[mls.Length + 1];
            _numberOfBits        = 1 + BinaryMath.Ld(mls.Length);

            bool[] seq = new bool[mls.Length];
            int    i   = 0;

            foreach (var e in mls.GetSequence(false, true))
            {
                seq[i++] = e;
            }

            GenerateResponsePermutationTable(seq, _responsePermutation, _numberOfBits);
            GenerateSignalPermutationTable(seq, _signalPermutation, _numberOfBits);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Returns the closest slice with
        /// </summary>
        /// <param name="z"></param>
        /// <returns></returns>
        public RegionOfInterestSlice GetClosestSlice(double z)
        {
            if (!ZRange.Contains(z))
            {
                return(null);
            }

            if (sliceDictionary.ContainsKey(z))
            {
                return(sliceDictionary[z]);
            }

            int index = BinaryMath.BinarySearchClosest(z, roiZCoordinates);
            RegionOfInterestSlice slice1 = null;
            RegionOfInterestSlice slice2 = null;

            if (!(index - 1 > RegionOfInterestSlices.Count - 1) && !(index - 1 < 0))
            {
                slice1 = RegionOfInterestSlices[index - 1];
            }
            if (!(index > RegionOfInterestSlices.Count - 1) && !(index < 0))
            {
                slice2 = RegionOfInterestSlices[index];
            }

            if (slice2 == null)
            {
                return(slice1);
            }
            if (slice1 == null)
            {
                return(slice2);
            }

            if (Math.Abs((slice1.ZCoord - z)) <= Math.Abs((slice2.ZCoord - z)))
            {
                return(slice1);
            }
            else
            {
                return(slice2);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Returns the closest slice with a z value greater than z
        /// </summary>
        /// <param name="z"></param>
        /// <returns></returns>
        public RegionOfInterestSlice GetClosestSliceNext(double z)
        {
            if (!ZRange.Contains(z))
            {
                return(null);
            }

            if (sliceDictionary.ContainsKey(z))
            {
                return(sliceDictionary[z]);
            }

            int index = BinaryMath.BinarySearchClosest(z, roiZCoordinates);

            if (!(index > RegionOfInterestSlices.Count - 1) && !(index < 0))
            {
                return(RegionOfInterestSlices[index]);
            }

            return(null);
        }
Ejemplo n.º 17
0
        public void AddPolygon(PlanarPolygon polygon)
        {
            if (!hasPolygon)
            {
                XRange  = polygon.XRange;
                YRange  = polygon.YRange;
                Rows    = (int)(polygon.YRange.Length / GridSpacing);
                Columns = (int)(polygon.XRange.Length / GridSpacing);

                // +2 to rows and cols to allow buffer of one row of false on top, left, bottom right.
                InsideBinaryData = new bool[(Rows) * (Columns)];
            }

            // Draw the new polygon to a boolean array
            bool[] polygonData = drawPolygon2(polygon);
            int    numTrue     = polygonData.Count(x => x == true);
            int    numOrigTrue = InsideBinaryData.Count(x => x == true);

            // Add the new polygon to the current inside binary data
            InsideBinaryData = BinaryMath.Xor(polygonData, InsideBinaryData);

            hasPolygon = true;
        }
Ejemplo n.º 18
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        /// <param name="bw"></param>
        /// <param name="bwSel"></param>
        /// <param name="adjust"></param>
        /// <param name="kernel"></param>
        /// <param name="weights"></param>
        /// <param name="width"></param>
        /// <param name="widthSel"></param>
        /// <param name="n"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="cut"></param>
        /// <remarks>Adapted from the R-project (www.r-project.org), Version 2.72, file density.R</remarks>
        public static ProbabilityDensityResult ProbabilityDensity(
            this IReadOnlyList <double> x,
            double bw,
            string bwSel,
            double adjust,
            ConvolutionKernel kernel,
            IReadOnlyList <double> weights,
            double width,
            string widthSel,
            int n,
            double from,
            double to,
            double cut // default: 3
            )
        {
            double wsum;

            if (null == weights)
            {
                weights = VectorMath.GetConstantVector(1.0 / x.Count, x.Count);
                wsum    = 1;
            }
            else
            {
                wsum = weights.Sum();
            }

            double totMass = 1;

            int n_user = n;

            n = Math.Max(n, 512);
            if (n > 512)
            {
                n = BinaryMath.NextPowerOfTwoGreaterOrEqualThan(n);
            }

            if (bw.IsNaN() && !(width.IsNaN() && null == widthSel))
            {
                if (!width.IsNaN())
                {
                    // S has width equal to the length of the support of the kernel
                    // except for the gaussian where it is 4 * sd.
                    // R has bw a multiple of the sd.
                    double fac = 1;
                    switch (kernel)
                    {
                    case ConvolutionKernel.Gaussian:
                        fac = 4;
                        break;

                    case ConvolutionKernel.Rectangular:
                        fac = 2 * Math.Sqrt(3);
                        break;

                    case ConvolutionKernel.Triangular:
                        fac = 2 * Math.Sqrt(6);
                        break;

                    case ConvolutionKernel.Epanechnikov:
                        fac = 2 * Math.Sqrt(5);
                        break;

                    case ConvolutionKernel.Biweight:
                        fac = 2 * Math.Sqrt(7);
                        break;

                    case ConvolutionKernel.Cosine:
                        fac = 2 / Math.Sqrt(1 / 3 - 2 / (Math.PI * Math.PI));
                        break;

                    case ConvolutionKernel.Optcosine:
                        fac = 2 / Math.Sqrt(1 - 8 / (Math.PI * Math.PI));
                        break;

                    default:
                        throw new ArgumentException("Unknown convolution kernel");
                    }
                    bw = width / fac;
                }
                else
                {
                    bwSel = widthSel;
                }
            }

            if (null != bwSel)
            {
                if (x.Count < 2)
                {
                    throw new ArgumentException("need at least 2 points to select a bandwidth automatically");
                }
                switch (bwSel.ToLowerInvariant())
                {
                case "nrd0":
                    //nrd0 = bw.nrd0(x),
                    break;

                case "nrd":
                    //nrd = bw.nrd(x),
                    break;

                case "ucv":
                    //ucv = bw.ucv(x),
                    break;

                case "bcv":
                    //bcv = bw.bcv(x),
                    break;

                case "sj":
                    //sj = , "sj-ste" = bw.SJ(x, method="ste"),
                    break;

                case "sj-dpi":
                    //"sj-dpi" = bw.SJ(x, method="dpi"),
                    break;

                default:
                    throw new ArgumentException("Unknown bandwith selection rule: " + bwSel.ToString());
                }
            }

            if (!RMath.IsFinite(bw))
            {
                throw new ArithmeticException("Bandwidth is not finite");
            }

            bw = adjust * bw;

            if (!(bw > 0))
            {
                throw new ArithmeticException("Bandwith is not positive");
            }

            if (from.IsNaN())
            {
                from = x.Min() - cut * bw;
            }
            if (to.IsNaN())
            {
                to = x.Max() + cut * bw;
            }

            if (!RMath.IsFinite(from))
            {
                throw new ArithmeticException("non-finite 'from'");
            }
            if (!to.IsFinite())
            {
                throw new ArithmeticException("non-finite 'to'");
            }
            double lo = from - 4 * bw;
            double up = to + 4 * bw;

            var y = new DoubleVector(2 * n);

            MassDistribution(x, weights, lo, up, y, n);
            y.Multiply(totMass);

            var kords = new DoubleVector(2 * n);

            kords.FillWithLinearSequenceGivenByStartAndEnd(0, 2 * (up - lo));

            for (int i = n + 1, j = n - 1; j >= 0; i++, j--)
            {
                kords[i] = -kords[j];
            }

            switch (kernel)
            {
            case ConvolutionKernel.Gaussian:
                kords.Map(new Probability.NormalDistribution(0, bw).PDF);
                break;

            case ConvolutionKernel.Rectangular:
                double a = bw * Math.Sqrt(3);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? 0.5 / a : 0); });
                break;

            case ConvolutionKernel.Triangular:
                a = bw * Math.Sqrt(6);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? (1 - Math.Abs(xx) / a) / a : 0); });
                break;

            case ConvolutionKernel.Epanechnikov:
                a = bw * Math.Sqrt(5);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? 0.75 * (1 - RMath.Pow2(Math.Abs(xx) / a)) / a : 0); });
                break;

            case ConvolutionKernel.Biweight:
                a = bw * Math.Sqrt(7);
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? 15.0 / 16.0 * RMath.Pow2(1 - RMath.Pow2(Math.Abs(xx) / a)) / a : 0); });
                break;

            case ConvolutionKernel.Cosine:
                a = bw / Math.Sqrt(1.0 / 3 - 2 / RMath.Pow2(Math.PI));
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? (1 + Math.Cos(Math.PI * xx / a)) / (2 * a) : 0); });
                break;

            case ConvolutionKernel.Optcosine:
                a = bw / Math.Sqrt(1 - 8 / RMath.Pow2(Math.PI));
                kords.Map(delegate(double xx)
                          { return(Math.Abs(xx) < a ? Math.PI / 4 * Math.Cos(Math.PI * xx / (2 * a)) / a : 0); });
                break;

            default:
                throw new ArgumentException("Unknown convolution kernel");
            }

            var result = new DoubleVector(2 * n);

            Fourier.FastHartleyTransform.CyclicRealConvolution(y.GetInternalData(), kords.GetInternalData(), result.GetInternalData(), 2 * n, null);
            y.Multiply(1.0 / (2 * n));
            VectorMath.MaxOf(y, 0, y);
            var xords = VectorMath.CreateEquidistantSequenceByStartEndLength(lo, up, n);
            var xu    = VectorMath.CreateEquidistantSequenceByStartEndLength(from, to, n_user);

            double[] res2 = new double[xu.Length];
            Interpolation.LinearInterpolation.Interpolate(xords, result, n, xu, xu.Length, 0, out res2);

            return(new ProbabilityDensityResult()
            {
                X = xu, Y = VectorMath.ToROVector(res2), Bandwidth = bw
            });
        }
Ejemplo n.º 19
0
        private void Mailmark()
        {
            int    inputLength   = barcodeData.Length;
            char   barcodeType   = 'C';
            int    formatId      = 0;
            int    versionId     = 0;
            int    classId       = 0;
            int    supplyChainId = 0;
            int    itemId        = 0;
            string postcode      = String.Empty;
            int    postcodeType  = 0;
            string pattern       = String.Empty;

            short[] destinationPostcode = new short[112];
            short[] aRegister           = new short[112];
            short[] bRegister           = new short[112];
            short[] tempRegister        = new short[112];
            short[] cdvRegister         = new short[112];
            byte[]  data = new byte[26];
            int     dataTop, dataStep;

            byte[]        check    = new byte[7];
            short[]       extender = new short[27];
            int           checkCount;
            StringBuilder barPattern = new StringBuilder();
            bool          result;

            if (inputLength > 26)
            {
                throw new InvalidDataLengthException("Mailmark: Input data too long.");
            }

            if (inputLength <= 22)
            {
                for (int i = inputLength; i < 22; i++)
                {
                    barcodeData = ArrayExtensions.Insert(barcodeData, inputLength, ' ');
                }

                inputLength = barcodeData.Length;
                barcodeType = 'C';
            }


            if (inputLength > 22 && inputLength <= 26)
            {
                for (int i = inputLength; i < 26; i++)
                {
                    barcodeData = ArrayExtensions.Insert(barcodeData, inputLength, ' ');
                }

                inputLength = barcodeData.Length;
                barcodeType = 'L';
            }

            for (int i = 0; i < inputLength; i++)
            {
                barcodeData[i] = Char.ToUpper(barcodeData[i], CultureInfo.CurrentCulture);  // Make sure all characters are uppercase.
                if (CharacterSets.Mailmark.IndexOf(barcodeData[i]) == -1)
                {
                    throw new InvalidDataException("Mailmark: Invalid character in input data.");
                }
            }

            // Format is in the range 0-4.
            result = int.TryParse((new string(barcodeData, 0, 1)), out formatId);
            if (!result || formatId < 0 || formatId > 4)
            {
                throw new InvalidDataException("Mailmark: Invalid Format character in input data.");
            }

            // Version ID is in the range 1-4.
            result = int.TryParse((new string(barcodeData, 1, 1)), out versionId);
            versionId--;    // Internal field value of 0-3.
            if (!result || versionId < 0 || versionId > 3)
            {
                throw new InvalidDataException("Mailmark: Invalid Version ID character in input data.");
            }

            // Class is in the range 0-9 & A-E.
            result = int.TryParse((new string(barcodeData, 2, 1)), NumberStyles.HexNumber, null, out classId);
            if (!result || classId < 0 || classId > 14)
            {
                throw new InvalidDataException("Mailmark: Invalid Class ID character in input data.");
            }

            // Supply Chain ID is 2 digits for barcode C and 6 digits for barcode L
            int supplyChainLength = (barcodeType == 'C') ? 2 : 6;

            result = int.TryParse(new string(barcodeData, 3, supplyChainLength), out supplyChainId);
            if (!result)
            {
                throw new InvalidDataException("Mailmark: Invalid Supply Chain ID character in input data.");
            }

            // Item ID is 8 digits.
            result = int.TryParse(new string(barcodeData, 3 + supplyChainLength, 8), out itemId);
            if (!result)
            {
                throw new InvalidDataException("Mailmark: Invalid Item ID character in input data.");
            }

            // Seperate Destination Post Code plus DPS field.
            postcode = new string(barcodeData, 3 + supplyChainLength + 8, 9);

            // Detect postcode type

            /* Postcode type is used to select which format of postcode
             *
             * 1 = FNFNLLNLS
             * 2 = FFNNLLNLS
             * 3 = FFNNNLLNL
             * 4 = FFNFNLLNL
             * 5 = FNNLLNLSS
             * 6 = FNNNLLNLS
             * 7 = International designation*/

            if (postcode == "XY11     ")
            {
                postcodeType = 7;
            }

            else
            {
                if (postcode[7] == ' ')
                {
                    postcodeType = 5;
                }

                else
                {
                    if (postcode[8] == ' ')
                    {
                        // Types 1, 2 and 6
                        if (Char.IsDigit(postcode[1]))
                        {
                            if (Char.IsDigit(postcode[2]))
                            {
                                postcodeType = 6;
                            }

                            else
                            {
                                postcodeType = 1;
                            }
                        }

                        else
                        {
                            postcodeType = 2;
                        }
                    }

                    else
                    {
                        // Types 3 and 4
                        if (Char.IsDigit(postcode[3]))
                        {
                            postcodeType = 3;
                        }

                        else
                        {
                            postcodeType = 4;
                        }
                    }
                }
            }

            // Verify postcode type
            if (postcodeType != 7)
            {
                if (!VerifyPostcode(postcode, postcodeType))
                {
                    throw new InvalidDataException("Mailmark: Invalid Postcode in input data.");
                }
            }

            // Convert postcode to internal user field.
            if (postcodeType != 7)
            {
                pattern = postcodeFormat[postcodeType - 1];
                BinaryMath.BinaryLoad(bRegister, "0");
                for (int i = 0; i < 9; i++)
                {
                    switch (pattern[i])
                    {
                    case 'F':
                        BinaryMath.BinaryMultiply(bRegister, "26");
                        BinaryMath.BinaryLoad(tempRegister, "0");
                        for (int j = 0; j < 5; j++)
                        {
                            if ((SetF.IndexOf(postcode[i]) & (0x01 << j)) > 0)
                            {
                                tempRegister[j] = 1;
                            }
                        }

                        BinaryMath.BinaryAdd(bRegister, tempRegister);
                        break;

                    case 'L':
                        BinaryMath.BinaryMultiply(bRegister, "20");
                        BinaryMath.BinaryLoad(tempRegister, "0");
                        for (int j = 0; j < 5; j++)
                        {
                            if ((SetL.IndexOf(postcode[i]) & (0x01 << j)) > 0)
                            {
                                tempRegister[j] = 1;
                            }
                        }

                        BinaryMath.BinaryAdd(bRegister, tempRegister);
                        break;

                    case 'N':
                        BinaryMath.BinaryMultiply(bRegister, "10");
                        BinaryMath.BinaryLoad(tempRegister, "0");
                        for (int j = 0; j < 5; j++)
                        {
                            if ((SetN.IndexOf(postcode[i]) & (0x01 << j)) > 0)
                            {
                                tempRegister[j] = 1;
                            }
                        }

                        BinaryMath.BinaryAdd(bRegister, tempRegister);
                        break;
                    }
                }

                // Destination postcode = accumulatorA + accumulatorB.
                BinaryMath.BinaryLoad(destinationPostcode, "0");
                BinaryMath.BinaryAdd(destinationPostcode, bRegister);

                BinaryMath.BinaryLoad(aRegister, "1");
                if (postcodeType == 1)
                {
                    BinaryMath.BinaryAdd(destinationPostcode, aRegister);
                }

                BinaryMath.BinaryLoad(tempRegister, "5408000000");
                BinaryMath.BinaryAdd(aRegister, tempRegister);

                if (postcodeType == 2)
                {
                    BinaryMath.BinaryAdd(destinationPostcode, aRegister);
                }

                BinaryMath.BinaryLoad(tempRegister, "5408000000");
                BinaryMath.BinaryAdd(aRegister, tempRegister);

                if (postcodeType == 3)
                {
                    BinaryMath.BinaryAdd(destinationPostcode, aRegister);
                }

                BinaryMath.BinaryLoad(tempRegister, "54080000000");
                BinaryMath.BinaryAdd(aRegister, tempRegister);

                if (postcodeType == 4)
                {
                    BinaryMath.BinaryAdd(destinationPostcode, aRegister);
                }

                BinaryMath.BinaryLoad(tempRegister, "140608000000");
                BinaryMath.BinaryAdd(aRegister, tempRegister);

                if (postcodeType == 5)
                {
                    BinaryMath.BinaryAdd(destinationPostcode, aRegister);
                }

                BinaryMath.BinaryLoad(tempRegister, "208000000");
                BinaryMath.BinaryAdd(aRegister, tempRegister);

                if (postcodeType == 6)
                {
                    BinaryMath.BinaryAdd(destinationPostcode, aRegister);
                }
            }

            // Conversion from Internal User Fields to Consolidated Data Value
            // Set CDV to 0
            BinaryMath.BinaryLoad(cdvRegister, "0");

            // Add Destination Post Code plus DPS
            BinaryMath.BinaryAdd(cdvRegister, destinationPostcode);

            // Multiply by 100,000,000
            BinaryMath.BinaryMultiply(cdvRegister, "100000000");

            // Add Item ID
            BinaryMath.BinaryLoad(tempRegister, "0");
            for (int i = 0; i < 32; i++)

            {
                if ((0x01 & (itemId >> i)) > 0)
                {
                    tempRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(cdvRegister, tempRegister);

            if (barcodeType == 'C')
            {
                BinaryMath.BinaryMultiply(cdvRegister, "100");  // Barcode C - Multiply by 100
            }
            else
            {
                BinaryMath.BinaryMultiply(cdvRegister, "1000000");  // Barcode L - Multiply by 1,000,000
            }
            // Add Supply Chain ID
            //int scCount = barcodeType == 'C' ? 7 : 20;
            BinaryMath.BinaryLoad(tempRegister, "0");
            for (int i = 0; i < 20; i++)
            {
                if ((0x01 & (supplyChainId >> i)) > 0)
                {
                    tempRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(cdvRegister, tempRegister);

            // Multiply by 15
            BinaryMath.BinaryMultiply(cdvRegister, "15");

            // Add Class
            BinaryMath.BinaryLoad(tempRegister, "0");
            for (int i = 0; i < 4; i++)
            {
                if ((0x01 & (classId >> i)) > 0)
                {
                    tempRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(cdvRegister, tempRegister);
            // Multiply by 5
            BinaryMath.BinaryMultiply(cdvRegister, "5");

            // Add Format
            BinaryMath.BinaryLoad(tempRegister, "0");
            for (int i = 0; i < 4; i++)
            {
                if ((0x01 & (formatId >> i)) > 0)
                {
                    tempRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(cdvRegister, tempRegister);

            // Multiply by 4
            BinaryMath.BinaryMultiply(cdvRegister, "4");
            // Add Version ID
            BinaryMath.BinaryLoad(tempRegister, "0");
            for (int i = 0; i < 4; i++)
            {
                if ((0x01 & (versionId >> i)) > 0)
                {
                    tempRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(cdvRegister, tempRegister);
            if (barcodeType == 'C')
            {
                dataTop    = 15;
                dataStep   = 8;
                checkCount = 6;
            }

            else
            {
                dataTop    = 18;
                dataStep   = 10;
                checkCount = 7;
            }

            // Conversion from Consolidated Data Value to Data Numbers
            for (int i = 0; i < 112; i++)
            {
                bRegister[i] = cdvRegister[i];
            }

            for (int j = dataTop; j >= (dataStep + 1); j--)
            {
                for (int i = 0; i < 112; i++)
                {
                    cdvRegister[i] = bRegister[i];
                    bRegister[i]   = 0;
                    aRegister[i]   = 0;
                }

                aRegister[96] = 1;
                for (int i = 91; i >= 0; i--)
                {
                    bRegister[i] = BinaryMath.IsLarger(cdvRegister, aRegister);
                    if (bRegister[i] == 1)
                    {
                        BinaryMath.BinarySubtract(cdvRegister, aRegister);
                    }

                    BinaryMath.ShiftDown(aRegister);
                }

                data[j] = (byte)((cdvRegister[5] * 32) + (cdvRegister[4] * 16) + (cdvRegister[3] * 8) + (cdvRegister[2] * 4) + (cdvRegister[1] * 2) + cdvRegister[0]);
            }

            for (int j = dataStep; j >= 0; j--)
            {
                for (int i = 0; i < 112; i++)
                {
                    cdvRegister[i] = bRegister[i];
                    bRegister[i]   = 0;
                    aRegister[i]   = 0;
                }

                aRegister[95] = 1;
                aRegister[94] = 1;
                aRegister[93] = 1;
                aRegister[92] = 1;
                for (int i = 91; i >= 0; i--)
                {
                    bRegister[i] = BinaryMath.IsLarger(cdvRegister, aRegister);
                    if (bRegister[i] == 1)
                    {
                        BinaryMath.BinarySubtract(cdvRegister, aRegister);
                    }

                    BinaryMath.ShiftDown(aRegister);
                }

                data[j] = (byte)((cdvRegister[5] * 32) + (cdvRegister[4] * 16) + (cdvRegister[3] * 8) + (cdvRegister[2] * 4) + (cdvRegister[1] * 2) + cdvRegister[0]);
            }

            ReedSolomon.RSInitialise(0x25, checkCount, 1);
            ReedSolomon.RSEncode(dataTop + 1, data, check);
            // Append check digits to data.
            for (int i = 1; i <= checkCount; i++)
            {
                data[dataTop + i] = check[checkCount - i];
            }

            // Conversion from Data Numbers and Check Numbers to Data Symbols and Check Symbols
            for (int i = 0; i <= dataStep; i++)
            {
                data[i] = dataSymbolEven[data[i]];
            }

            for (int i = dataStep + 1; i <= (dataTop + checkCount); i++)
            {
                data[i] = dataSymbolOdd[data[i]];
            }

            // Conversion from Data Symbols and Check Symbols to Extender Groups
            for (int i = 0; i < inputLength; i++)
            {
                if (barcodeType == 'C')
                {
                    extender[extenderGroupC[i]] = data[i];
                }

                else
                {
                    extender[extenderGroupL[i]] = data[i];
                }
            }

            // Conversion from Extender Groups to Bar Identifiers
            for (int i = 0; i < inputLength; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    switch (extender[i] & 0x24)
                    {
                    case 0x24:
                        barPattern.Append("F");
                        break;

                    case 0x20:
                        if (i % 2 > 0)
                        {
                            barPattern.Append("D");
                        }

                        else
                        {
                            barPattern.Append("A");
                        }

                        break;

                    case 0x04:
                        if (i % 2 > 0)
                        {
                            barPattern.Append("A");
                        }

                        else
                        {
                            barPattern.Append("D");
                        }

                        break;

                    default:
                        barPattern.Append("T");
                        break;
                    }

                    extender[i] = (short)(extender[i] << 1);
                }
            }

            BuildSymbol(barPattern);
            barcodeText = new string(barcodeData);
        }
Ejemplo n.º 20
0
        public void GetLeastSignificant0BitPosition_SampleValues_ReturnsExpectedBitPosition()
        {
            var result = numbers.Select(i => BinaryMath.GetLeastSignificant0BitPosition(i));

            Assert.That(result, Is.EqualTo(expectedLow0Bits));
        }
Ejemplo n.º 21
0
        private void IntellgentMail()
        {
            int       index;
            int       value;
            string    zip      = String.Empty;
            string    tracker  = String.Empty;
            BitVector zipAdder = new BitVector();

            short[] accumulator = new short[112];
            short[] xRegister   = new short[112];
            short[] yRegister   = new short[112];
            byte[]  byteData    = new byte[13];
            uint    uspsCRC;

            int[]         codeword    = new int[10];
            uint[]        characters  = new uint[10];
            int[]         barMap      = new int[130];
            StringBuilder barPattern  = new StringBuilder();
            int           inputLength = barcodeData.Length;

            if (inputLength > 31)
            {
                throw new InvalidDataLengthException("USPS: Input data too long.");
            }

            if (inputLength < 20)
            {
                throw new InvalidDataLengthException("USPS: Invalid tracking code length.");
            }

            // Separate the tracking code from the routing code.
            tracker = new string(barcodeData, 0, 20);
            if (inputLength > 20)
            {
                zip = new string(barcodeData, 20, inputLength - tracker.Length);
            }

            if (zip.Length != 11 && zip.Length != 9 && zip.Length != 5 && zip.Length != 0)
            {
                throw new InvalidDataException("USPS: Invalid ZIP code.");
            }

            Array.Clear(accumulator, 0, 112);
            for (index = 0; index < zip.Length; index++)
            {
                BinaryMath.BinaryMultiply(accumulator, "10");
                BinaryMath.BinaryLoad(xRegister, "0");
                for (int i = 0; i < 4; i++)
                {
                    value = zip[index] - '0';
                    if ((value & (0x01 << i)) > 0)
                    {
                        xRegister[i] = 1;
                    }
                }

                BinaryMath.BinaryAdd(accumulator, xRegister);
            }

            // Add weight to routing code.
            Array.Copy(accumulator, xRegister, 112);
            if (zip.Length > 9)
            {
                zipAdder.AppendBits(545, 10);       // 1000100001
            }
            else
            {
                if (zip.Length > 5)
                {
                    zipAdder.AppendBits(33, 6);     // 100001
                }
                else
                {
                    if (zip.Length > 0)
                    {
                        zipAdder.AppendBit(1);      // 1
                    }
                    else
                    {
                        zipAdder.AppendBit(0);      // 0
                    }
                }
            }

            Array.Clear(accumulator, 0, 112);
            for (index = 0; index < zipAdder.SizeInBits; index++)
            {
                BinaryMath.BinaryMultiply(accumulator, "10");
                BinaryMath.BinaryLoad(yRegister, "0");
                for (int i = 0; i < 4; i++)
                {
                    value = zipAdder[index] - '0';
                    if ((value & (0x01 << i)) > 0)
                    {
                        yRegister[i] = 1;
                    }
                }

                BinaryMath.BinaryAdd(accumulator, yRegister);
            }

            BinaryMath.BinaryAdd(accumulator, xRegister);

            // Tracking code.
            // Multiply by 10.
            BinaryMath.BinaryMultiply(accumulator, "10");
            BinaryMath.BinaryLoad(yRegister, "0");
            for (int i = 0; i < 4; i++)
            {
                value = tracker[0] - '0';
                if ((value & (0x01 << i)) > 0)
                {
                    yRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(accumulator, yRegister);

            // Multiply by 5.
            BinaryMath.BinaryMultiply(accumulator, "5");
            BinaryMath.BinaryLoad(yRegister, "0");
            // Add second digit.
            for (int i = 0; i < 4; i++)
            {
                value = tracker[1] - '0';
                if ((value & (0x01 << i)) > 0)
                {
                    yRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(accumulator, yRegister);

            // And then the rest.
            for (index = 2; index < tracker.Length; index++)
            {
                BinaryMath.BinaryMultiply(accumulator, "10");
                BinaryMath.BinaryLoad(yRegister, "0");
                for (int i = 0; i < 4; i++)
                {
                    value = tracker[index] - '0';
                    if ((value & (0x01 << i)) > 0)
                    {
                        yRegister[i] = 1;
                    }
                }

                BinaryMath.BinaryAdd(accumulator, yRegister);
            }

            // Step 2 - Generation of 11-bit CRC on Binary Data.
            accumulator[103] = 0;
            accumulator[102] = 0;

            for (int i = 0; i < 13; i++)
            {
                int j = 96 - (8 * i);
                byteData[i]  = 0;
                byteData[i] += (byte)accumulator[j];
                byteData[i] += (byte)(2 * accumulator[j + 1]);
                byteData[i] += (byte)(4 * accumulator[j + 2]);
                byteData[i] += (byte)(8 * accumulator[j + 3]);
                byteData[i] += (byte)(16 * accumulator[j + 4]);
                byteData[i] += (byte)(32 * accumulator[j + 5]);
                byteData[i] += (byte)(64 * accumulator[j + 6]);
                byteData[i] += (byte)(128 * accumulator[j + 7]);
            }

            uspsCRC = CRC11GenerateFrameCheckSequence(byteData);

            // Step 3 - Conversion from Binary Data to Codewords.
            // Start with codeword J which is base 636
            Array.Clear(xRegister, 0, 112);
            Array.Clear(yRegister, 0, 112);

            xRegister[101] = 1;
            xRegister[98]  = 1;
            xRegister[97]  = 1;
            xRegister[96]  = 1;
            xRegister[95]  = 1;
            xRegister[94]  = 1;

            for (int i = 92; i >= 0; i--)
            {
                yRegister[i] = BinaryMath.IsLarger(accumulator, xRegister);
                if (yRegister[i] == 1)
                {
                    BinaryMath.BinarySubtract(accumulator, xRegister);
                }

                BinaryMath.ShiftDown(xRegister);
            }

            codeword[9] = (accumulator[9] * 512) + (accumulator[8] * 256) + (accumulator[7] * 128) + (accumulator[6] * 64) +
                          (accumulator[5] * 32) + (accumulator[4] * 16) + (accumulator[3] * 8) + (accumulator[2] * 4) +
                          (accumulator[1] * 2) + accumulator[0];

            // Then codewords I to B with base 1365.
            for (int j = 8; j > 0; j--)
            {
                for (int i = 0; i < 112; i++)
                {
                    accumulator[i] = yRegister[i];
                    yRegister[i]   = 0;
                    xRegister[i]   = 0;
                }

                xRegister[101] = 1;
                xRegister[99]  = 1;
                xRegister[97]  = 1;
                xRegister[95]  = 1;
                xRegister[93]  = 1;
                xRegister[91]  = 1;
                for (int i = 91; i >= 0; i--)
                {
                    yRegister[i] = BinaryMath.IsLarger(accumulator, xRegister);
                    if (yRegister[i] == 1)
                    {
                        BinaryMath.BinarySubtract(accumulator, xRegister);
                    }

                    BinaryMath.ShiftDown(xRegister);
                }

                codeword[j] = (accumulator[10] * 1024) + (accumulator[9] * 512) + (accumulator[8] * 256) +
                              (accumulator[7] * 128) + (accumulator[6] * 64) + (accumulator[5] * 32) +
                              (accumulator[4] * 16) + (accumulator[3] * 8) + (accumulator[2] * 4) +
                              (accumulator[1] * 2) + accumulator[0];
            }

            codeword[0] = (yRegister[10] * 1024) + (yRegister[9] * 512) + (yRegister[8] * 256) +
                          (yRegister[7] * 128) + (yRegister[6] * 64) + (yRegister[5] * 32) +
                          (yRegister[4] * 16) + (yRegister[3] * 8) + (yRegister[2] * 4) +
                          (yRegister[1] * 2) + yRegister[0];

            for (int i = 0; i < 8; i++)
            {
                if (codeword[i] == 1365)
                {
                    codeword[i] = 0;
                    codeword[i + 1]++;
                }
            }

            // Step 4 - Inserting Additional Information into Codewords.
            codeword[9] = codeword[9] * 2;
            if (uspsCRC >= 1024)
            {
                codeword[0] += 659;
            }

            // Step 5 - Conversion from Codewords to Characters.
            for (int i = 0; i < 10; i++)
            {
                if (codeword[i] < 1287)
                {
                    characters[i] = AppendixD1[codeword[i]];
                }

                else
                {
                    characters[i] = AppendixD2[codeword[i] - 1287];
                }
            }

            for (int i = 0; i < 10; i++)
            {
                if ((uspsCRC & (1 << i)) > 0)
                {
                    characters[i] = 0x1FFF - characters[i];
                }
            }

            // Step 6 - Conversion from Characters to the Intelligent Mail Barcode.
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 13; j++)
                {
                    if ((characters[i] & (1 << j)) > 0)
                    {
                        barMap[AppendixD4[(13 * i) + j] - 1] = 1;
                    }

                    else
                    {
                        barMap[AppendixD4[(13 * i) + j] - 1] = 0;
                    }
                }
            }

            for (int i = 0; i < 65; i++)
            {
                int j = 0;
                if (barMap[i] == 0)
                {
                    j += 1;
                }

                if (barMap[i + 65] == 0)
                {
                    j += 2;
                }

                barPattern.Append(j);
            }

            SymbolBuilder.BuildFourStateSymbol(Symbol, barPattern);
            // Format the barcodes text.
            barcodeText = new string(barcodeData);
            if (zip.Length > 0)
            {
                if (zip.Length == 11)
                {
                    barcodeText = barcodeText.Insert(29, " ");
                }

                if (zip.Length >= 9)
                {
                    barcodeText = barcodeText.Insert(25, " ");
                }

                if (zip.Length >= 5)
                {
                    barcodeText = barcodeText.Insert(20, " ");
                }
            }

            if (tracker[5] < '9')
            {
                barcodeText = barcodeText.Insert(11, " ");
            }

            else
            {
                barcodeText = barcodeText.Insert(14, " ");
            }

            barcodeText = barcodeText.Insert(5, " ");
            barcodeText = barcodeText.Insert(2, " ");
        }
Ejemplo n.º 22
0
 public AstBinaryMathOperation(BinaryMath op, AstExpression left, AstExpression right, Position position) : base(position)
 {
     Op    = op;
     Left  = left;
     Right = right;
 }