예제 #1
1
        public void Add()
        {
            var criteria = new List<IIterationStopCriterium>
                           {
                               new FailureStopCriterium(),
                               new DivergenceStopCriterium(),
                               new IterationCountStopCriterium(),
                               new ResidualStopCriterium()
                           };
            var iterator = new Iterator();
            Assert.AreEqual(0, iterator.NumberOfCriteria, "Incorrect criterium count");

            foreach (var criterium in criteria)
            {
                iterator.Add(criterium);
                Assert.IsTrue(iterator.Contains(criterium), "Missing criterium");
            }

            // Check that we have all the criteria
            Assert.AreEqual(criteria.Count, iterator.NumberOfCriteria, "Incorrect criterium count");
            var enumerator = iterator.StoredStopCriteria;
            while (enumerator.MoveNext())
            {
                var criterium = enumerator.Current;
                Assert.IsTrue(criteria.Exists(c => ReferenceEquals(c, criterium)), "Criterium missing");
            }
        }
예제 #2
0
        public void DetermineStatus()
        {
            var criteria = new List<IIterationStopCriterium<Complex32>>
            {
                new FailureStopCriterium<Complex32>(),
                new DivergenceStopCriterium<Complex32>(),
                new IterationCountStopCriterium<Complex32>(1)
            };

            var iterator = new Iterator<Complex32>(criteria);

            // First step, nothing should happen.
            iterator.DetermineStatus(
                0,
                Vector<Complex32>.Build.Dense(3, 4),
                Vector<Complex32>.Build.Dense(3, 4),
                Vector<Complex32>.Build.Dense(3, 4));
            Assert.AreEqual(IterationStatus.Continue, iterator.Status, "Incorrect status");

            // Second step, should run out of iterations.
            iterator.DetermineStatus(
                1,
                Vector<Complex32>.Build.Dense(3, 4),
                Vector<Complex32>.Build.Dense(3, 4),
                Vector<Complex32>.Build.Dense(3, 4));
            Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status");
        }
예제 #3
0
        public void CanSolveForRandomMatrix(int order)
        {
            var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
            var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order);

            var monitor = new Iterator(new IIterationStopCriterium<Complex>[]
                                       {
                                           new IterationCountStopCriterium(1000),
                                           new ResidualStopCriterium(1e-10),
                                       });
            var solver = new MlkBiCgStab(monitor);
            var matrixX = solver.Solve(matrixA, matrixB);

            // The solution X row dimension is equal to the column dimension of A
            Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
            // The solution X has the same number of columns as B
            Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);

            var matrixBReconstruct = matrixA * matrixX;

            // Check the reconstruction.
            for (var i = 0; i < matrixB.RowCount; i++)
            {
                for (var j = 0; j < matrixB.ColumnCount; j++)
                {
                    Assert.AreApproximatelyEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1.0e-5);
                    Assert.AreApproximatelyEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1.0e-5);
                }
            }
        }
예제 #4
0
        public string PrintMenu(Iterator iterator)

        {

            StringBuilder sb = new StringBuilder();

            while(iterator.HasNext())

            {

                MenuItem menuItem = (MenuItem)iterator.Next();



                sb.Append(menuItem.Name + ", ");

                sb.Append(menuItem.Price + " -- ");

                sb.Append(menuItem.Description + "\n");

            }



            return sb.ToString();

        }
예제 #5
0
        public void DetermineStatus()
        {
            var criteria = new List<IIterationStopCriterium<float>>
                {
                    new FailureStopCriterium(),
                    new DivergenceStopCriterium(),
                    new IterationCountStopCriterium<float>(1)
                };

            var iterator = new Iterator<float>(criteria);

            // First step, nothing should happen.
            iterator.DetermineStatus(
                0,
                DenseVector.Create(3, i => 4),
                DenseVector.Create(3, i => 4),
                DenseVector.Create(3, i => 4));
            Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");

            // Second step, should run out of iterations.
            iterator.DetermineStatus(
                1,
                DenseVector.Create(3, i => 4),
                DenseVector.Create(3, i => 4),
                DenseVector.Create(3, i => 4));
            Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status");
        }
예제 #6
0
        public void CanSolveForRandomMatrix([Values(4, 8, 10)] int order)
        {
            var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
            var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order);

            var monitor = new Iterator(new IIterationStopCriterium[]
                                       {
                                           new IterationCountStopCriterium(1000),
                                           new ResidualStopCriterium(1e-10)
                                       });
            var solver = new TFQMR(monitor);
            var matrixX = solver.Solve(matrixA, matrixB);

            // The solution X row dimension is equal to the column dimension of A
            Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

            // The solution X has the same number of columns as B
            Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);

            var matrixBReconstruct = matrixA * matrixX;
            // Check the reconstruction.
            for (var i = 0; i < matrixB.RowCount; i++)
            {
                for (var j = 0; j < matrixB.ColumnCount; j++)
                {
                    Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1.0e-7);
                }
            }
        }
예제 #7
0
        public void Clone()
        {
            var criteria = new List<IIterationStopCriterium<Complex32>>
                           {
                               new FailureStopCriterium(),
                               new DivergenceStopCriterium(),
                               new IterationCountStopCriterium(),
                               new ResidualStopCriterium()
                           };

            var iterator = new Iterator(criteria);

            var clonedIterator = iterator.Clone();
            Assert.IsInstanceOfType(typeof(Iterator), clonedIterator, "Incorrect type");

            var clone = clonedIterator as Iterator;
            Assert.IsNotNull(clone);
            // ReSharper disable PossibleNullReferenceException
            Assert.AreEqual(iterator.NumberOfCriteria, clone.NumberOfCriteria, "Incorrect criterium count");
            // ReSharper restore PossibleNullReferenceException

            var enumerator = clone.StoredStopCriteria;
            while (enumerator.MoveNext())
            {
                var criterium = enumerator.Current;
                Assert.IsTrue(criteria.Exists(c => c.GetType().Equals(criterium.GetType())), "Criterium missing");
            }
        }
예제 #8
0
 public static void DisplayMemberList(Iterator.IIterator iterator)
 {
     while (!iterator.IsDone())
     {
         Console.WriteLine(iterator.Next());
     }
 }
예제 #9
0
 public void TestNext()
 {
     IEnumerable<DayOfWeek> collection = new DayOfWeek[] { DayOfWeek.Monday, DayOfWeek.Friday };
     var iterator = new Iterator<DayOfWeek>(collection.GetEnumerator());
     Assert.AreEqual(DayOfWeek.Monday, iterator.Next());
     Assert.AreEqual(DayOfWeek.Friday, iterator.Next());
     ExceptionAssert.Throws<InvalidOperationException>(() => iterator.Next());
 }
예제 #10
0
        public void AddWithExistingStopCriterium()
        {
            var iterator = new Iterator();
            iterator.Add(new FailureStopCriterium());
            Assert.AreEqual(1, iterator.NumberOfCriteria, "Incorrect criterium count");

            iterator.Add(new FailureStopCriterium());
        }
 public override Iterator createIterator()
 {
     if (iterator == null)
     {
         iterator = new BankWindowIterator(components);
     }
     return iterator;
 }
예제 #12
0
        public void TheSumOfAllMultiplesOf3Or5Below10Equals23()
        {
            var iterator = new Iterator<int>(0, 10, isMultipleOf3Or5, i => i + 1);
            var aggregator = new Aggregator(iterator);

            int result = aggregator.GetSum();
            Assert.That(result, Is.EqualTo(23));
        }
예제 #13
0
 private void add_to_player_iterator(Iterator iterator,BrandPlayer player)
 {
     while (iterator.hasNext())
     {
         Brand brand = (Brand)iterator.next();
         player.add(brand);
     }
 }
예제 #14
0
        public void IteratorThrowsExceptionIfNextValueIsLessThanCurrentValue()
        {
            var isMatch = MockRepository.GenerateStub<Predicate<int>>();
            var iterator = new Iterator<int>(0, 2, isMatch, i => i - 1);

            var total = 0;
            iterator.Visit(i => total += i);
        }
예제 #15
0
        public void AddWithExistingStopCriteriumThrowsArgumentException()
        {
            var iterator = new Iterator();
            iterator.Add(new FailureStopCriterium());
            Assert.AreEqual(1, iterator.NumberOfCriteria, "Incorrect criterium count");

            Assert.Throws<ArgumentException>(() => iterator.Add(new FailureStopCriterium()));
        }
예제 #16
0
 public void DetermineStatusWithoutStopCriteriaDoesNotThrow()
 {
     var iterator = new Iterator<Complex32>();
     Assert.DoesNotThrow(() => iterator.DetermineStatus(
         0,
         DenseVector.Create(3, i => 4),
         DenseVector.Create(3, i => 5),
         DenseVector.Create(3, i => 6)));
 }
예제 #17
0
 public void TestHasNextEmpty()
 {
     var iterator = new Iterator<DayOfWeek>(null as IEnumerable<DayOfWeek>);
     Assert.IsFalse(iterator.HasNext);
     iterator = new Iterator<DayOfWeek>(null as IEnumerator<DayOfWeek>);
     Assert.IsFalse(iterator.HasNext);
     iterator = new Iterator<DayOfWeek>(Enumerable.Empty<DayOfWeek>());
     Assert.IsFalse(iterator.HasNext);
 }
예제 #18
0
 public void DetermineStatusWithoutStopCriteriaDoesNotThrow()
 {
     var iterator = new Iterator<float>();
     Assert.DoesNotThrow(() => iterator.DetermineStatus(
         0,
         Vector<float>.Build.Dense(3, 4),
         Vector<float>.Build.Dense(3, 5),
         Vector<float>.Build.Dense(3, 6)));
 }
예제 #19
0
파일: AiTest.cs 프로젝트: billteng/mahjong
 private void print(Iterator iterator)
 {
     //Console.WriteLine();
     while (iterator.hasNext())
     {
         Brand brand = (Brand)iterator.next();
         Console.Write("{0}{1}\t", brand.getNumber(), brand.getClass() );
     }
 }
예제 #20
0
        public void CanSumAllMultiplesOf3Or5Below1000()
        {
            var iterator = new Iterator<int>(0, 1000, isMultipleOf3Or5, i => i + 1);
            var aggregator = new Aggregator(iterator);

            int result = aggregator.GetSum();

            // Not asserting the answer here, as I can't find what the accepted answer is.
            Trace.WriteLine(string.Format("Result: {0}", result)); // returns 33165.
        }
예제 #21
0
        public void IteratorDoesNotCheckFirstElementForMatchIfMinimumIsGreaterThanMaximum()
        {
            var isMatch = MockRepository.GenerateStub<Predicate<int>>();
            var iterator = new Iterator<int>(3, 0, isMatch, i => i + 1);

            var total = 0;
            iterator.Visit(i => total += i);

            isMatch.AssertWasNotCalled(im => im.Invoke(3));
        }
예제 #22
0
        public void IteratorDoesNotConsiderIncludingMaximumNumberInSequence()
        {
            var isMatch = MockRepository.GenerateStub<Predicate<int>>();
            var iterator = new Iterator<int>(0, 2, isMatch, i => i + 1);

            var total = 0;
            iterator.Visit(i => total += i);

            isMatch.AssertWasNotCalled(im => im.Invoke(2));
        }
예제 #23
0
        public void IteratorChecksAllNumbersInSequenceToSeeIfTheyMatchTheCriteria()
        {
            var isMatch = MockRepository.GenerateStub<Predicate<int>>();
            var iterator = new Iterator<int>(0, 2, isMatch, i => i + 1);

            var total = 0;
            iterator.Visit(i => total += i);

            isMatch.AssertWasCalled(im => im.Invoke(0));
            isMatch.AssertWasCalled(im => im.Invoke(1));
        }
예제 #24
0
 public void TestHasNext()
 {
     var collection = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>();
     var iterator = new Iterator<DayOfWeek>(collection.GetEnumerator());
     for (int i = 0; i < collection.Count(); i++)
     {
         Assert.IsTrue(iterator.HasNext);
         iterator.Next();
     }
     Assert.IsFalse(iterator.HasNext);
 }
 public override void deleteIterator()
 {
     iterator = null;
     for (int i = 0; i < components.Count; i++)
     {
         if (components[i].GetType() == typeof(BankWindowComposite))
         {
             components[i].deleteIterator();
         }
     }
 }
예제 #26
0
파일: Iterator.cs 프로젝트: alexflorea/CN
        /// <summary>
        /// Creates a convergence monitor.
        /// </summary>
        public void UseMonitor()
        {
            // Set the maximum increase in residual that we allow before
            // stopping the iteration because of divergence.
            double maximumIncrease = 0.1;

            // Set the maximum number of iterations that the convergence monitor
            // will allow before indicating that the iteration must be stopped.
            int maximumNumberOfIterations = 100;

            // Set the value the residual must maximally have before the
            // convergence monitor will declare that the iteration has converged.
            // Note that this residual is relative to the starting point which is
            // determined by the matrix norm.
            double minimumResidual = 1E-5;

            List<IIterationStopCriterium> criteria = new List<IIterationStopCriterium>();
            criteria.Add(new FailureStopCriterium());
            criteria.Add(new DivergenceStopCriterium(maximumIncrease));
            criteria.Add(new IterationCountStopCriterium(maximumNumberOfIterations));
            criteria.Add(new ResidualStopCriterium(minimumResidual));

            // Create the iterator
            Iterator monitor = new Iterator(criteria);

            // To be able to use the convergence monitor we'll need a solution vector and
            // a residual vector. For now fill both with silly numbers.
            Vector sourceVector = new DenseVector(10, 3.5);
            Vector solutionVector = new DenseVector(10, 2.5);
            Vector residualVector = new DenseVector(10, 1.5);

            // Check the solution status. There should not be a real status because
            // we haven't done anything yet
            Console.WriteLine("Solution status: " + monitor.Status.ToString());

            // Now use the monitor in a fake iteration. If all goes well this iteration should
            // stop because the number of iterations becomes larger than the number of iterations
            // we allow.
            int currentIteration = 0;
            while ((monitor.Status is CalculationRunning) || (monitor.Status is CalculationIndetermined))
            {
                currentIteration++;
                Console.WriteLine("Working. Iteration no: " + currentIteration.ToString());
                monitor.DetermineStatus(currentIteration, solutionVector, sourceVector, residualVector);
            }

            // Indicate that we exited the loop
            Console.WriteLine("Stopped working.");
            // Indicate why we exited the loop. Note that this should say
            // SolutionStatus.IterationBoundsReached.
            Console.WriteLine("Stop reason: " + monitor.Status.ToString());
        }
예제 #27
0
        public void TestSkipMultiple()
        {
            List<string> list = new List<string>();
            list.Add("1");
            list.Add("2");
            list.Add("3");

            Iterator<string> iter = new Iterator<string>(list);

            iter.Skip(2);
            Assert.IsTrue(iter.HasNext());
            Assert.AreEqual(list[2], iter.Next());
        }
예제 #28
0
 public ReadOnlyIterator(Iterator it)
 {
   base.\u002Ector();
   ReadOnlyIterator readOnlyIterator = this;
   if (it == null)
   {
     string str = "Base iterator is null.";
     Throwable.__\u003CsuppressFillInStackTrace\u003E();
     throw new NullPointerException(str);
   }
   else
     this.@base = it;
 }
예제 #29
0
        public void TestHasNext()
        {
            List<string> list = new List<string>();
            list.Add("1");
            list.Add("2");
            list.Add("3");

            Iterator<string> iter = new Iterator<string>(list);

            Assert.IsTrue(iter.HasNext(1));
            Assert.IsTrue(iter.HasNext(2));
            Assert.IsTrue(iter.HasNext(3));
            Assert.IsFalse(iter.HasNext(4));
        }
예제 #30
0
        public void IteratorUsesIncrementExpressionToAdvanceThroughTheSequence()
        {
            var increment = MockRepository.GenerateStub<Func<int, int>>();
            increment.Stub(inc => inc.Invoke(0)).Return(1);
            increment.Stub(inc => inc.Invoke(1)).Return(2);

            var iterator = new Iterator<int>(0, 2, i => true, increment);

            var total = 0;
            iterator.Visit(i => total += i);

            increment.AssertWasCalled(im => im.Invoke(0));
            increment.AssertWasCalled(im => im.Invoke(1));
        }
예제 #31
0
파일: ListBase.cs 프로젝트: ggeurts/nhive
 protected abstract void OnInsertRange <TInputSize, TInput>
     (Iterator insertBegin, IHive <T, TInputSize, TInput> range, out Range <T, TSize, Iterator> insertedRange)
     where TInput : struct, IInputIterator <T, TInputSize, TInput>
     where TInputSize : struct, IConvertible;
예제 #32
0
 public override bool LessThan(Iterator a, Iterator b)
 {
     return(a.WordNum < b.WordNum);
 }
예제 #33
0
        public void NextOnEmptySet()
        {
            var iterator = new Iterator <int>(new int[] {});

            Assert.That(() => iterator.Next(), Throws.InstanceOf <IndexOutOfRangeException>());
        }
예제 #34
0
        public void CurrentOnEmptySet()
        {
            var iterator = new Iterator <int>(new int[] { });

            Assert.That(() => iterator.Current(), Throws.Exception);
        }
예제 #35
0
        public void EofOnEmptySet()
        {
            var iterator = new Iterator <int>(new int[] { });

            Assert.That(() => iterator.Eof(), Is.False);
        }
예제 #36
0
 [SetUp] public void Setup() => i = new TIterator(new Sequence());
예제 #37
0
 public static IteratorEnumerator <T> AsEnumerator <T>(this Iterator <T> it)
 {
     return(new IteratorEnumerator <T>(it));
 }
        /// <exception cref="NGit.Errors.TransportException"></exception>
        private bool DownloadPackedObject(ProgressMonitor monitor, AnyObjectId id)
        {
            // Search for the object in a remote pack whose index we have,
            // but whose pack we do not yet have.
            //
            Iterator <WalkFetchConnection.RemotePack> packItr = unfetchedPacks.Iterator();

            while (packItr.HasNext() && !monitor.IsCancelled())
            {
                WalkFetchConnection.RemotePack pack = packItr.Next();
                try
                {
                    pack.OpenIndex(monitor);
                }
                catch (IOException err)
                {
                    // If the index won't open its either not found or
                    // its a format we don't recognize. In either case
                    // we may still be able to obtain the object from
                    // another source, so don't consider it a failure.
                    //
                    RecordError(id, err);
                    packItr.Remove();
                    continue;
                }
                if (monitor.IsCancelled())
                {
                    // If we were cancelled while the index was opening
                    // the open may have aborted. We can't search an
                    // unopen index.
                    //
                    return(false);
                }
                if (!pack.index.HasObject(id))
                {
                    // Not in this pack? Try another.
                    //
                    continue;
                }
                // It should be in the associated pack. Download that
                // and attach it to the local repository so we can use
                // all of the contained objects.
                //
                try
                {
                    pack.DownloadPack(monitor);
                }
                catch (IOException err)
                {
                    // If the pack failed to download, index correctly,
                    // or open in the local repository we may still be
                    // able to obtain this object from another pack or
                    // an alternate.
                    //
                    RecordError(id, err);
                    continue;
                }
                finally
                {
                    // If the pack was good its in the local repository
                    // and Repository.hasObject(id) will succeed in the
                    // future, so we do not need this data anymore. If
                    // it failed the index and pack are unusable and we
                    // shouldn't consult them again.
                    //
                    try
                    {
                        if (pack.tmpIdx != null)
                        {
                            FileUtils.Delete(pack.tmpIdx);
                        }
                    }
                    catch (IOException e)
                    {
                        throw new TransportException(e.Message, e);
                    }
                    packItr.Remove();
                }
                if (!AlreadyHave(id))
                {
                    // What the hell? This pack claimed to have
                    // the object, but after indexing we didn't
                    // actually find it in the pack.
                    //
                    RecordError(id, new FileNotFoundException(MessageFormat.Format(JGitText.Get().objectNotFoundIn
                                                                                   , id.Name, pack.packName)));
                    continue;
                }
                // Complete any other objects that we can.
                //
                Iterator <ObjectId> pending = SwapFetchQueue();
                while (pending.HasNext())
                {
                    ObjectId p = pending.Next();
                    if (pack.index.HasObject(p))
                    {
                        pending.Remove();
                        Process(p);
                    }
                    else
                    {
                        workQueue.AddItem(p);
                    }
                }
                return(true);
            }
            return(false);
        }
예제 #39
0
 public _Iterator_391(Iterator it)
 {
     this.it = it;
 }
예제 #40
0
        public void SolvePoissonMatrixAndBackMultiply()
        {
            // Create the matrix
            var matrix = new SparseMatrix(25);

            // Assemble the matrix. We assume we're solving the Poisson equation
            // on a rectangular 5 x 5 grid
            const int GridSize = 5;

            // The pattern is:
            // 0 .... 0 -1 0 0 0 0 0 0 0 0 -1 4 -1 0 0 0 0 0 0 0 0 -1 0 0 ... 0
            for (var i = 0; i < matrix.RowCount; i++)
            {
                // Insert the first set of -1's
                if (i > (GridSize - 1))
                {
                    matrix[i, i - GridSize] = -1;
                }

                // Insert the second set of -1's
                if (i > 0)
                {
                    matrix[i, i - 1] = -1;
                }

                // Insert the centerline values
                matrix[i, i] = 4;

                // Insert the first trailing set of -1's
                if (i < matrix.RowCount - 1)
                {
                    matrix[i, i + 1] = -1;
                }

                // Insert the second trailing set of -1's
                if (i < matrix.RowCount - GridSize)
                {
                    matrix[i, i + GridSize] = -1;
                }
            }

            // Create the y vector
            var y = Vector <float> .Build.Dense(matrix.RowCount, 1);

            // Create an iteration monitor which will keep track of iterative convergence
            var monitor = new Iterator <float>(
                new IterationCountStopCriterion <float>(MaximumIterations),
                new ResidualStopCriterion <float>(ConvergenceBoundary),
                new DivergenceStopCriterion <float>(),
                new FailureStopCriterion <float>());

            var solver = new TFQMR();

            // Solve equation Ax = y
            var x = matrix.SolveIterative(y, solver, monitor);

            // Now compare the results
            Assert.IsNotNull(x, "#02");
            Assert.AreEqual(y.Count, x.Count, "#03");

            // Back multiply the vector
            var z = matrix.Multiply(x);

            // Check that the solution converged
            Assert.IsTrue(monitor.Status == IterationStatus.Converged, "#04");

            // Now compare the vectors
            Assert.LessOrEqual(Distance.Chebyshev(y, z), 2 * ConvergenceBoundary);
        }
예제 #41
0
 public void Set(Tensor tensor)
 {
     Iterator.Set(tensor);
 }
예제 #42
0
        public void Resume(Object eventTarget)
        {
            if (GuiThreadHelper.IsInGuiThread())
            {
                // Nothing to do
                return;
            }
            IEventTargetExtractor eventTargetExtractor = typeToEventTargetExtractorsDict.GetExtension(eventTarget.GetType());

            if (eventTargetExtractor == null)
            {
                return;
            }
            eventTarget = eventTargetExtractor.ExtractEventTarget(eventTarget);
            if (eventTarget == null)
            {
                return;
            }
            IdentityLinkedSet <WaitForResumeItem> freeLatchMap = null;

            try
            {
                PausedEventTargetItem pauseETI;
                listenersWriteLock.Lock();
                try
                {
                    IdentityLinkedMap <Object, PausedEventTargetItem> pausedTargets = this.pausedTargets;
                    pauseETI = pausedTargets.Get(eventTarget);
                    if (pauseETI == null)
                    {
                        throw new System.Exception("No pause() active for target " + eventTarget);
                    }
                    pauseETI.PauseCount--;
                    if (pauseETI.PauseCount > 0)
                    {
                        return;
                    }
                    pausedTargets.Remove(eventTarget);

                    IList <Object>               remainingPausedEventTargets    = EvaluatePausedEventTargets();
                    IdentityHashSet <Object>     remainingPausedEventTargetsSet = new IdentityHashSet <Object>();
                    Iterator <WaitForResumeItem> iter = waitForResumeSet.Iterator();
                    while (iter.MoveNext())
                    {
                        WaitForResumeItem pauseItem = iter.Current;
                        remainingPausedEventTargetsSet.AddAll(remainingPausedEventTargets);
                        remainingPausedEventTargetsSet.RetainAll(pauseItem.PendingPauses);

                        if (remainingPausedEventTargetsSet.Count == 0)
                        {
                            iter.Remove();
                            if (freeLatchMap == null)
                            {
                                freeLatchMap = new IdentityLinkedSet <WaitForResumeItem>();
                            }
                            freeLatchMap.Add(pauseItem);
                        }
                        remainingPausedEventTargetsSet.Clear();
                    }
                }
                finally
                {
                    listenersWriteLock.Unlock();
                }
            }
            finally
            {
                if (freeLatchMap != null)
                {
                    foreach (WaitForResumeItem wfrItem in freeLatchMap)
                    {
                        wfrItem.Latch.CountDown();
                    }
                    foreach (WaitForResumeItem wfrItem in freeLatchMap)
                    {
                        try
                        {
                            wfrItem.ResultLatch.Await();
                        }
                        catch (System.Exception e)
                        {
                            throw new System.Exception("Fatal state occured. This may result in a global deadlock", e);
                        }
                    }
                }
            }
        }
예제 #43
0
        /// <summary>
        /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
        /// solution vector and x is the unknown vector.
        /// </summary>
        /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
        /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
        /// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
        /// <param name="iterator">The iterator to use to control when to stop iterating.</param>
        /// <param name="preconditioner">The preconditioner to use for approximations.</param>
        public void Solve(Matrix <double> matrix, Vector <double> input, Vector <double> result, Iterator <double> iterator, IPreconditioner <double> preconditioner)
        {
            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare, nameof(matrix));
            }

            if (result.Count != input.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength);
            }

            if (input.Count != matrix.RowCount)
            {
                throw Matrix.DimensionsDontMatch <ArgumentException>(input, matrix);
            }

            if (iterator == null)
            {
                iterator = new Iterator <double>();
            }

            if (preconditioner == null)
            {
                preconditioner = new UnitPreconditioner <double>();
            }

            preconditioner.Initialize(matrix);

            // Compute r_0 = b - Ax_0 for some initial guess x_0
            // In this case we take x_0 = vector
            // This is basically a SAXPY so it could be made a lot faster
            var residuals = new DenseVector(matrix.RowCount);

            CalculateTrueResidual(matrix, residuals, result, input);

            // Choose r~ (for example, r~ = r_0)
            var tempResiduals = residuals.Clone();

            // create seven temporary vectors needed to hold temporary
            // coefficients. All vectors are mangled in each iteration.
            // These are defined here to prevent stressing the garbage collector
            var vecP     = new DenseVector(residuals.Count);
            var vecPdash = new DenseVector(residuals.Count);
            var nu       = new DenseVector(residuals.Count);
            var vecS     = new DenseVector(residuals.Count);
            var vecSdash = new DenseVector(residuals.Count);
            var temp     = new DenseVector(residuals.Count);
            var temp2    = new DenseVector(residuals.Count);

            // create some temporary double variables that are needed
            // to hold values in between iterations
            double currentRho = 0;
            double alpha      = 0;
            double omega      = 0;

            var iterationNumber = 0;

            while (iterator.DetermineStatus(iterationNumber, result, input, residuals) == IterationStatus.Continue)
            {
                // rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1)
                var oldRho = currentRho;
                currentRho = tempResiduals.DotProduct(residuals);

                // if (rho_(i-1) == 0) // METHOD FAILS
                // If rho is only 1 ULP from zero then we fail.
                if (currentRho.AlmostEqualNumbersBetween(0, 1))
                {
                    // Rho-type breakdown
                    throw new NumericalBreakdownException();
                }

                if (iterationNumber != 0)
                {
                    // beta_(i-1) = (rho_(i-1)/rho_(i-2))(alpha_(i-1)/omega(i-1))
                    var beta = (currentRho / oldRho) * (alpha / omega);

                    // p_i = r_(i-1) + beta_(i-1)(p_(i-1) - omega_(i-1) * nu_(i-1))
                    nu.Multiply(-omega, temp);
                    vecP.Add(temp, temp2);
                    temp2.CopyTo(vecP);

                    vecP.Multiply(beta, vecP);
                    vecP.Add(residuals, temp2);
                    temp2.CopyTo(vecP);
                }
                else
                {
                    // p_i = r_(i-1)
                    residuals.CopyTo(vecP);
                }

                // SOLVE Mp~ = p_i // M = preconditioner
                preconditioner.Approximate(vecP, vecPdash);

                // nu_i = Ap~
                matrix.Multiply(vecPdash, nu);

                // alpha_i = rho_(i-1)/ (r~^T nu_i) = rho / dotproduct(r~ and nu_i)
                alpha = currentRho * 1 / tempResiduals.DotProduct(nu);

                // s = r_(i-1) - alpha_i nu_i
                nu.Multiply(-alpha, temp);
                residuals.Add(temp, vecS);

                // Check if we're converged. If so then stop. Otherwise continue;
                // Calculate the temporary result.
                // Be careful not to change any of the temp vectors, except for
                // temp. Others will be used in the calculation later on.
                // x_i = x_(i-1) + alpha_i * p^_i + s^_i
                vecPdash.Multiply(alpha, temp);
                temp.Add(vecSdash, temp2);
                temp2.CopyTo(temp);
                temp.Add(result, temp2);
                temp2.CopyTo(temp);

                // Check convergence and stop if we are converged.
                if (iterator.DetermineStatus(iterationNumber, temp, input, vecS) != IterationStatus.Continue)
                {
                    temp.CopyTo(result);

                    // Calculate the true residual
                    CalculateTrueResidual(matrix, residuals, result, input);

                    // Now recheck the convergence
                    if (iterator.DetermineStatus(iterationNumber, result, input, residuals) != IterationStatus.Continue)
                    {
                        // We're all good now.
                        return;
                    }

                    // Continue the calculation
                    iterationNumber++;
                    continue;
                }

                // SOLVE Ms~ = s
                preconditioner.Approximate(vecS, vecSdash);

                // temp = As~
                matrix.Multiply(vecSdash, temp);

                // omega_i = temp^T s / temp^T temp
                omega = temp.DotProduct(vecS) / temp.DotProduct(temp);

                // x_i = x_(i-1) + alpha_i p^ + omega_i s^
                temp.Multiply(-omega, residuals);
                residuals.Add(vecS, temp2);
                temp2.CopyTo(residuals);

                vecSdash.Multiply(omega, temp);
                result.Add(temp, temp2);
                temp2.CopyTo(result);

                vecPdash.Multiply(alpha, temp);
                result.Add(temp, temp2);
                temp2.CopyTo(result);

                // for continuation it is necessary that omega_i != 0.0
                // If omega is only 1 ULP from zero then we fail.
                if (omega.AlmostEqualNumbersBetween(0, 1))
                {
                    // Omega-type breakdown
                    throw new NumericalBreakdownException();
                }

                if (iterator.DetermineStatus(iterationNumber, result, input, residuals) != IterationStatus.Continue)
                {
                    // Recalculate the residuals and go round again. This is done to ensure that
                    // we have the proper residuals.
                    // The residual calculation based on omega_i * s can be off by a factor 10. So here
                    // we calculate the real residual (which can be expensive) but we only do it if we're
                    // sufficiently close to the finish.
                    CalculateTrueResidual(matrix, residuals, result, input);
                }

                iterationNumber++;
            }
        }
예제 #44
0
 public Tensor Result()
 {
     return(Iterator.Result());
 }
        /// <summary>
        /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
        /// solution vector and x is the unknown vector.
        /// </summary>
        /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
        /// <param name="input">The solution vector, <c>b</c></param>
        /// <param name="result">The result vector, <c>x</c></param>
        public void Solve(Matrix <double> matrix, Vector <double> input, Vector <double> result)
        {
            // If we were stopped before, we are no longer
            // We're doing this at the start of the method to ensure
            // that we can use these fields immediately.
            _hasBeenStopped = false;

            // Error checks
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare, "matrix");
            }

            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            if (result.Count != input.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength);
            }

            if (input.Count != matrix.RowCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixDimensions);
            }

            // Initialize the solver fields
            // Set the convergence monitor
            if (_iterator == null)
            {
                _iterator = Iterator.CreateDefault();
            }

            if (_preconditioner == null)
            {
                _preconditioner = new UnitPreconditioner();
            }

            _preconditioner.Initialize(matrix);

            var d = new DenseVector(input.Count);
            var r = new DenseVector(input);

            var uodd  = new DenseVector(input.Count);
            var ueven = new DenseVector(input.Count);

            var v = new DenseVector(input.Count);
            var pseudoResiduals = new DenseVector(input);

            var x     = new DenseVector(input.Count);
            var yodd  = new DenseVector(input.Count);
            var yeven = new DenseVector(input);

            // Temp vectors
            var temp  = new DenseVector(input.Count);
            var temp1 = new DenseVector(input.Count);
            var temp2 = new DenseVector(input.Count);

            // Initialize
            var startNorm = input.Norm(2);

            // Define the scalars
            double alpha = 0;
            double eta   = 0;
            double theta = 0;

            var tau = startNorm;
            var rho = tau * tau;

            // Calculate the initial values for v
            // M temp = yEven
            _preconditioner.Approximate(yeven, temp);

            // v = A temp
            matrix.Multiply(temp, v);

            // Set uOdd
            v.CopyTo(ueven);

            // Start the iteration
            var iterationNumber = 0;

            while (ShouldContinue(iterationNumber, result, input, pseudoResiduals))
            {
                // First part of the step, the even bit
                if (IsEven(iterationNumber))
                {
                    // sigma = (v, r)
                    var sigma = v.DotProduct(r);
                    if (sigma.AlmostEqual(0, 1))
                    {
                        // FAIL HERE
                        _iterator.IterationCancelled();
                        break;
                    }

                    // alpha = rho / sigma
                    alpha = rho / sigma;

                    // yOdd = yEven - alpha * v
                    v.Multiply(-alpha, temp1);
                    yeven.Add(temp1, yodd);

                    // Solve M temp = yOdd
                    _preconditioner.Approximate(yodd, temp);

                    // uOdd = A temp
                    matrix.Multiply(temp, uodd);
                }

                // The intermediate step which is equal for both even and
                // odd iteration steps.
                // Select the correct vector
                var uinternal = IsEven(iterationNumber) ? ueven : uodd;
                var yinternal = IsEven(iterationNumber) ? yeven : yodd;

                // pseudoResiduals = pseudoResiduals - alpha * uOdd
                uinternal.Multiply(-alpha, temp1);
                pseudoResiduals.Add(temp1, temp2);
                temp2.CopyTo(pseudoResiduals);

                // d = yOdd + theta * theta * eta / alpha * d
                d.Multiply(theta * theta * eta / alpha, temp);
                yinternal.Add(temp, d);

                // theta = ||pseudoResiduals||_2 / tau
                theta = pseudoResiduals.Norm(2) / tau;
                var c = 1 / Math.Sqrt(1 + (theta * theta));

                // tau = tau * theta * c
                tau *= theta * c;

                // eta = c^2 * alpha
                eta = c * c * alpha;

                // x = x + eta * d
                d.Multiply(eta, temp1);
                x.Add(temp1, temp2);
                temp2.CopyTo(x);

                // Check convergence and see if we can bail
                if (!ShouldContinue(iterationNumber, result, input, pseudoResiduals))
                {
                    // Calculate the real values
                    _preconditioner.Approximate(x, result);

                    // Calculate the true residual. Use the temp vector for that
                    // so that we don't pollute the pseudoResidual vector for no
                    // good reason.
                    CalculateTrueResidual(matrix, temp, result, input);

                    // Now recheck the convergence
                    if (!ShouldContinue(iterationNumber, result, input, temp))
                    {
                        // We're all good now.
                        return;
                    }
                }

                // The odd step
                if (!IsEven(iterationNumber))
                {
                    if (rho.AlmostEqual(0, 1))
                    {
                        // FAIL HERE
                        _iterator.IterationCancelled();
                        break;
                    }

                    var rhoNew = pseudoResiduals.DotProduct(r);
                    var beta   = rhoNew / rho;

                    // Update rho for the next loop
                    rho = rhoNew;

                    // yOdd = pseudoResiduals + beta * yOdd
                    yodd.Multiply(beta, temp1);
                    pseudoResiduals.Add(temp1, yeven);

                    // Solve M temp = yOdd
                    _preconditioner.Approximate(yeven, temp);

                    // uOdd = A temp
                    matrix.Multiply(temp, ueven);

                    // v = uEven + beta * (uOdd + beta * v)
                    v.Multiply(beta, temp1);
                    uodd.Add(temp1, temp);

                    temp.Multiply(beta, temp1);
                    ueven.Add(temp1, v);
                }

                // Calculate the real values
                _preconditioner.Approximate(x, result);

                iterationNumber++;
            }
        }
 private void EmitIteratorInitialization(int from)
 {
     new ValueOperand(from).EmitLoad(_processor);
     Iterator.EmitStore(_processor);
 }
        /// <summary>
        /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
        /// solution vector and x is the unknown vector.
        /// </summary>
        /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
        /// <param name="input">The solution vector, <c>b</c></param>
        /// <param name="result">The result vector, <c>x</c></param>
        public void Solve(Matrix matrix, Vector input, Vector result)
        {
            // If we were stopped before, we are no longer
            // We're doing this at the start of the method to ensure
            // that we can use these fields immediately.
            _hasBeenStopped = false;
            _currentSolver  = null;

            // Error checks
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare, "matrix");
            }

            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            if (result.Count != input.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength);
            }

            // Initialize the solver fields
            // Set the convergence monitor
            if (_iterator == null)
            {
                _iterator = Iterator.CreateDefault();
            }

            // Load the solvers into our own internal data structure
            // Once we have solvers we can always reuse them.
            if (_solvers.Count == 0)
            {
                LoadSolvers();
            }

            // Create a copy of the solution and result vectors so we can use them
            // later on
            var internalInput  = (Vector)input.Clone();
            var internalResult = (Vector)result.Clone();

            foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped))
            {
                // Store a reference to the solver so we can stop it.
                _currentSolver = solver;

                try
                {
                    // Reset the iterator and pass it to the solver
                    _iterator.ResetToPrecalculationState();
                    solver.SetIterator(_iterator);

                    // Start the solver
                    solver.Solve(matrix, internalInput, internalResult);
                }
                catch (Exception)
                {
                    // The solver broke down.
                    // Log a message about this
                    // Switch to the next preconditioner.
                    // Reset the solution vector to the previous solution
                    input.CopyTo(internalInput);
                    _status = RunningStatus;
                    continue;
                }

                // There was no fatal breakdown so check the status
                if (_iterator.Status is CalculationConverged)
                {
                    // We're done
                    internalResult.CopyTo(result);
                    break;
                }

                // We're not done
                // Either:
                // - calculation finished without convergence
                if (_iterator.Status is CalculationStoppedWithoutConvergence)
                {
                    // Copy the internal result to the result vector and
                    // continue with the calculation.
                    internalResult.CopyTo(result);
                }
                else
                {
                    // - calculation failed --> restart with the original vector
                    // - calculation diverged --> restart with the original vector
                    // - Some unknown status occurred --> To be safe restart.
                    input.CopyTo(internalInput);
                }
            }

            // Inside the loop we already copied the final results (if there are any)
            // So no need to do that again.

            // Clean up
            // No longer need the current solver
            _currentSolver = null;

            // Set the final status
            _status = _iterator.Status;
        }
예제 #48
0
        /// <summary>
        /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
        /// solution vector and x is the unknown vector.
        /// </summary>
        /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
        /// <param name="input">The solution vector, <c>b</c></param>
        /// <param name="result">The result vector, <c>x</c></param>
        public void Solve(Matrix <Complex> matrix, Vector <Complex> input, Vector <Complex> result)
        {
            // If we were stopped before, we are no longer
            // We're doing this at the start of the method to ensure
            // that we can use these fields immediately.
            _hasBeenStopped = false;

            // Error checks
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }

            if (matrix.RowCount != matrix.ColumnCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixSquare, "matrix");
            }

            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            if (result.Count != input.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength);
            }

            if (input.Count != matrix.RowCount)
            {
                throw new ArgumentException(Resources.ArgumentMatrixDimensions);
            }

            // Initialize the solver fields
            // Set the convergence monitor
            if (_iterator == null)
            {
                _iterator = Iterator.CreateDefault();
            }

            if (_preconditioner == null)
            {
                _preconditioner = new UnitPreconditioner();
            }

            _preconditioner.Initialize(matrix);

            // Choose an initial guess x_0
            // Take x_0 = 0
            Vector <Complex> xtemp = new DenseVector(input.Count);

            // Choose k vectors q_1, q_2, ..., q_k
            // Build a new set if:
            // a) the stored set doesn't exist (i.e. == null)
            // b) Is of an incorrect length (i.e. too long)
            // c) The vectors are of an incorrect length (i.e. too long or too short)
            var useOld = false;

            if (_startingVectors != null)
            {
                // We don't accept collections with zero starting vectors so ...
                if (_startingVectors.Count <= NumberOfStartingVectorsToCreate(_numberOfStartingVectors, input.Count))
                {
                    // Only check the first vector for sizing. If that matches we assume the
                    // other vectors match too. If they don't the process will crash
                    if (_startingVectors[0].Count == input.Count)
                    {
                        useOld = true;
                    }
                }
            }

            _startingVectors = useOld ? _startingVectors : CreateStartingVectors(_numberOfStartingVectors, input.Count);

            // Store the number of starting vectors. Not really necessary but easier to type :)
            var k = _startingVectors.Count;

            // r_0 = b - Ax_0
            // This is basically a SAXPY so it could be made a lot faster
            Vector <Complex> residuals = new DenseVector(matrix.RowCount);

            CalculateTrueResidual(matrix, residuals, xtemp, input);

            // Define the temporary values
            var c = new Complex[k];

            // Define the temporary vectors
            Vector <Complex> gtemp = new DenseVector(residuals.Count);

            Vector <Complex> u     = new DenseVector(residuals.Count);
            Vector <Complex> utemp = new DenseVector(residuals.Count);
            Vector <Complex> temp  = new DenseVector(residuals.Count);
            Vector <Complex> temp1 = new DenseVector(residuals.Count);
            Vector <Complex> temp2 = new DenseVector(residuals.Count);

            Vector <Complex> zd = new DenseVector(residuals.Count);
            Vector <Complex> zg = new DenseVector(residuals.Count);
            Vector <Complex> zw = new DenseVector(residuals.Count);

            var d = CreateVectorArray(_startingVectors.Count, residuals.Count);

            // g_0 = r_0
            var g = CreateVectorArray(_startingVectors.Count, residuals.Count);

            residuals.CopyTo(g[k - 1]);

            var w = CreateVectorArray(_startingVectors.Count, residuals.Count);

            // FOR (j = 0, 1, 2 ....)
            var iterationNumber = 0;

            while (ShouldContinue(iterationNumber, xtemp, input, residuals))
            {
                // SOLVE M g~_((j-1)k+k) = g_((j-1)k+k)
                _preconditioner.Approximate(g[k - 1], gtemp);

                // w_((j-1)k+k) = A g~_((j-1)k+k)
                matrix.Multiply(gtemp, w[k - 1]);

                // c_((j-1)k+k) = q^T_1 w_((j-1)k+k)
                c[k - 1] = _startingVectors[0].DotProduct(w[k - 1]);
                if (c[k - 1].Real.AlmostEqual(0, 1) && c[k - 1].Imaginary.AlmostEqual(0, 1))
                {
                    throw new Exception("Iterative solver experience a numerical break down");
                }

                // alpha_(jk+1) = q^T_1 r_((j-1)k+k) / c_((j-1)k+k)
                var alpha = _startingVectors[0].DotProduct(residuals) / c[k - 1];

                // u_(jk+1) = r_((j-1)k+k) - alpha_(jk+1) w_((j-1)k+k)
                w[k - 1].Multiply(-alpha, temp);
                residuals.Add(temp, u);

                // SOLVE M u~_(jk+1) = u_(jk+1)
                _preconditioner.Approximate(u, temp1);
                temp1.CopyTo(utemp);

                // rho_(j+1) = -u^t_(jk+1) A u~_(jk+1) / ||A u~_(jk+1)||^2
                matrix.Multiply(temp1, temp);
                var rho = temp.DotProduct(temp);

                // If rho is zero then temp is a zero vector and we're probably
                // about to have zero residuals (i.e. an exact solution).
                // So set rho to 1.0 because in the next step it will turn to zero.
                if (rho.Real.AlmostEqual(0, 1) && rho.Imaginary.AlmostEqual(0, 1))
                {
                    rho = 1.0;
                }

                rho = -u.DotProduct(temp) / rho;

                // r_(jk+1) = rho_(j+1) A u~_(jk+1) + u_(jk+1)
                u.CopyTo(residuals);

                // Reuse temp
                temp.Multiply(rho, temp);
                residuals.Add(temp, temp2);
                temp2.CopyTo(residuals);

                // x_(jk+1) = x_((j-1)k_k) - rho_(j+1) u~_(jk+1) + alpha_(jk+1) g~_((j-1)k+k)
                utemp.Multiply(-rho, temp);
                xtemp.Add(temp, temp2);
                temp2.CopyTo(xtemp);

                gtemp.Multiply(alpha, gtemp);
                xtemp.Add(gtemp, temp2);
                temp2.CopyTo(xtemp);

                // Check convergence and stop if we are converged.
                if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
                {
                    // Calculate the true residual
                    CalculateTrueResidual(matrix, residuals, xtemp, input);

                    // Now recheck the convergence
                    if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
                    {
                        // We're all good now.
                        // Exit from the while loop.
                        break;
                    }
                }

                // FOR (i = 1,2, ...., k)
                for (var i = 0; i < k; i++)
                {
                    // z_d = u_(jk+1)
                    u.CopyTo(zd);

                    // z_g = r_(jk+i)
                    residuals.CopyTo(zg);

                    // z_w = 0
                    zw.Clear();

                    // FOR (s = i, ...., k-1) AND j >= 1
                    Complex beta;
                    if (iterationNumber >= 1)
                    {
                        for (var s = i; s < k - 1; s++)
                        {
                            // beta^(jk+i)_((j-1)k+s) = -q^t_(s+1) z_d / c_((j-1)k+s)
                            beta = -_startingVectors[s + 1].DotProduct(zd) / c[s];

                            // z_d = z_d + beta^(jk+i)_((j-1)k+s) d_((j-1)k+s)
                            d[s].Multiply(beta, temp);
                            zd.Add(temp, temp2);
                            temp2.CopyTo(zd);

                            // z_g = z_g + beta^(jk+i)_((j-1)k+s) g_((j-1)k+s)
                            g[s].Multiply(beta, temp);
                            zg.Add(temp, temp2);
                            temp2.CopyTo(zg);

                            // z_w = z_w + beta^(jk+i)_((j-1)k+s) w_((j-1)k+s)
                            w[s].Multiply(beta, temp);
                            zw.Add(temp, temp2);
                            temp2.CopyTo(zw);
                        }
                    }

                    beta = rho * c[k - 1];
                    if (beta.Real.AlmostEqual(0, 1) && beta.Imaginary.AlmostEqual(0, 1))
                    {
                        throw new Exception("Iterative solver experience a numerical break down");
                    }

                    // beta^(jk+i)_((j-1)k+k) = -(q^T_1 (r_(jk+1) + rho_(j+1) z_w)) / (rho_(j+1) c_((j-1)k+k))
                    zw.Multiply(rho, temp2);
                    residuals.Add(temp2, temp);
                    beta = -_startingVectors[0].DotProduct(temp) / beta;

                    // z_g = z_g + beta^(jk+i)_((j-1)k+k) g_((j-1)k+k)
                    g[k - 1].Multiply(beta, temp);
                    zg.Add(temp, temp2);
                    temp2.CopyTo(zg);

                    // z_w = rho_(j+1) (z_w + beta^(jk+i)_((j-1)k+k) w_((j-1)k+k))
                    w[k - 1].Multiply(beta, temp);
                    zw.Add(temp, temp2);
                    temp2.CopyTo(zw);
                    zw.Multiply(rho, zw);

                    // z_d = r_(jk+i) + z_w
                    residuals.Add(zw, zd);

                    // FOR (s = 1, ... i - 1)
                    for (var s = 0; s < i - 1; s++)
                    {
                        // beta^(jk+i)_(jk+s) = -q^T_s+1 z_d / c_(jk+s)
                        beta = -_startingVectors[s + 1].DotProduct(zd) / c[s];

                        // z_d = z_d + beta^(jk+i)_(jk+s) * d_(jk+s)
                        d[s].Multiply(beta, temp);
                        zd.Add(temp, temp2);
                        temp2.CopyTo(zd);

                        // z_g = z_g + beta^(jk+i)_(jk+s) * g_(jk+s)
                        g[s].Multiply(beta, temp);
                        zg.Add(temp, temp2);
                        temp2.CopyTo(zg);
                    }

                    // d_(jk+i) = z_d - u_(jk+i)
                    zd.Subtract(u, d[i]);

                    // g_(jk+i) = z_g + z_w
                    zg.Add(zw, g[i]);

                    // IF (i < k - 1)
                    if (i < k - 1)
                    {
                        // c_(jk+1) = q^T_i+1 d_(jk+i)
                        c[i] = _startingVectors[i + 1].DotProduct(d[i]);
                        if (c[i].Real.AlmostEqual(0, 1) && c[i].Imaginary.AlmostEqual(0, 1))
                        {
                            throw new Exception("Iterative solver experience a numerical break down");
                        }

                        // alpha_(jk+i+1) = q^T_(i+1) u_(jk+i) / c_(jk+i)
                        alpha = _startingVectors[i + 1].DotProduct(u) / c[i];

                        // u_(jk+i+1) = u_(jk+i) - alpha_(jk+i+1) d_(jk+i)
                        d[i].Multiply(-alpha, temp);
                        u.Add(temp, temp2);
                        temp2.CopyTo(u);

                        // SOLVE M g~_(jk+i) = g_(jk+i)
                        _preconditioner.Approximate(g[i], gtemp);

                        // x_(jk+i+1) = x_(jk+i) + rho_(j+1) alpha_(jk+i+1) g~_(jk+i)
                        gtemp.Multiply(rho * alpha, temp);
                        xtemp.Add(temp, temp2);
                        temp2.CopyTo(xtemp);

                        // w_(jk+i) = A g~_(jk+i)
                        matrix.Multiply(gtemp, w[i]);

                        // r_(jk+i+1) = r_(jk+i) - rho_(j+1) alpha_(jk+i+1) w_(jk+i)
                        w[i].Multiply(-rho * alpha, temp);
                        residuals.Add(temp, temp2);
                        temp2.CopyTo(residuals);

                        // We can check the residuals here if they're close
                        if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
                        {
                            // Recalculate the residuals and go round again. This is done to ensure that
                            // we have the proper residuals.
                            CalculateTrueResidual(matrix, residuals, xtemp, input);
                        }
                    }
                } // END ITERATION OVER i

                iterationNumber++;
            }

            // copy the temporary result to the real result vector
            xtemp.CopyTo(result);
        }
        public void SolvePoissonMatrixAndBackMultiply()
        {
            // Create the matrix
            var matrix = new SparseMatrix(100);

            // Assemble the matrix. We assume we're solving the Poisson equation
            // on a rectangular 10 x 10 grid
            const int GridSize = 10;

            // The pattern is:
            // 0 .... 0 -1 0 0 0 0 0 0 0 0 -1 4 -1 0 0 0 0 0 0 0 0 -1 0 0 ... 0
            for (var i = 0; i < matrix.RowCount; i++)
            {
                // Insert the first set of -1's
                if (i > (GridSize - 1))
                {
                    matrix[i, i - GridSize] = -1;
                }

                // Insert the second set of -1's
                if (i > 0)
                {
                    matrix[i, i - 1] = -1;
                }

                // Insert the centerline values
                matrix[i, i] = 4;

                // Insert the first trailing set of -1's
                if (i < matrix.RowCount - 1)
                {
                    matrix[i, i + 1] = -1;
                }

                // Insert the second trailing set of -1's
                if (i < matrix.RowCount - GridSize)
                {
                    matrix[i, i + GridSize] = -1;
                }
            }

            // Create the y vector
            Vector y = new DenseVector(matrix.RowCount, 1);

            // Create an iteration monitor which will keep track of iterative convergence
            var monitor = new Iterator(new IIterationStopCriterium[]
            {
                new IterationCountStopCriterium(MaximumIterations),
                new ResidualStopCriterium(ConvergenceBoundary),
                new DivergenceStopCriterium(),
                new FailureStopCriterium()
            });
            var solver = new MlkBiCgStab(monitor);

            // Solve equation Ax = y
            var x = solver.Solve(matrix, y);

            // Now compare the results
            Assert.IsNotNull(x, "#02");
            Assert.AreEqual(y.Count, x.Count, "#03");

            // Back multiply the vector
            var z = matrix.Multiply(x);

            // Check that the solution converged
            Assert.IsTrue(monitor.Status is CalculationConverged, "#04");

            // Now compare the vectors
            for (var i = 0; i < y.Count; i++)
            {
#if !PORTABLE
                Assert.IsTrue(Math.Abs(y[i] - z[i]).IsSmaller(ConvergenceBoundary, 1), "#05-" + i);
#else
                Assert.IsTrue(Math.Abs(y[i] - z[i]).IsSmaller(ConvergenceBoundary * 100.0, 1), "#05-" + i);
#endif
            }
        }
예제 #50
0
 public Task <IEnumerable <TResult> > Pairs <TValue, TResult>(TValue value, Iterator iterator)
 {
     throw new NotImplementedException();
 }
예제 #51
0
        public void CurrentOnFullSet()
        {
            var iterator = new Iterator <int>(new int[] { 1, 2, 3 });

            Assert.That(() => iterator.Current(), Is.EqualTo(1));
        }
예제 #52
0
 public uint Count <TKey>(TKey key, Iterator it = Iterator.Eq)
 {
     throw new NotImplementedException();
 }
예제 #53
0
        public void NextOnFullSet()
        {
            var iterator = new Iterator <int>(new int[] { 1, 2, 3 });

            Assert.That(() => iterator.Next(), Is.EqualTo(2));
        }
예제 #54
0
        public void TestPut2()
        {
            hm.Put("KEY", "VALUE");
            Assert.AreEqual("VALUE", hm.Get("KEY"), "Assert.Failed to install key/value pair");

            HashMap <Object, Object> m = new HashMap <Object, Object>();

            m.Put(0, "short");
            m.Put(null, "test");
            m.Put(0, "int");
            Assert.AreEqual("int", m.Get(0), "Assert.Failed adding to bucket containing null");
            Assert.AreEqual("int", m.Get(0), "Assert.Failed adding to bucket containing null2");

            // Check my actual key instance is returned
            HashMap <Object, String> map = new HashMap <Object, String>();

            for (int i = -32767; i < 32768; i++)
            {
                map.Put(i, "foobar");
            }
            Object myKey = 0;

            // Put a new value at the old key position
            map.Put(myKey, "myValue");
            Assert.IsTrue(map.ContainsKey(myKey));
            Assert.AreEqual("myValue", map.Get(myKey));
            bool found = false;

            for (Iterator <Object> itr = map.KeySet().Iterator(); itr.HasNext;)
            {
                Object key = itr.Next();
                if (found = key == myKey)
                {
                    break;
                }
            }

            Assert.IsFalse(found, "Should not find new key instance in hashmap");

            // Add a new key instance and check it is returned
            Assert.IsNotNull(map.Remove(myKey));
            map.Put(myKey, "myValue");
            Assert.IsTrue(map.ContainsKey(myKey));
            Assert.AreEqual(map.Get(myKey), "myValue");
            for (Iterator <Object> itr = map.KeySet().Iterator(); itr.HasNext;)
            {
                Object key = itr.Next();
                if (found = key == myKey)
                {
                    break;
                }
            }
            Assert.IsTrue(found, "Did not find new key instance in hashmap");

            // Ensure keys with identical hashcode are stored separately
            HashMap <Object, Object> objmap = new HashMap <Object, Object>();

            for (int i = 0; i < 32768; i++)
            {
                objmap.Put(i, "foobar");
            }
            // Put non-equal object with same hashcode
            MyKey aKey = new MyKey();

            Assert.IsNull(objmap.Put(aKey, "value"));
            Assert.IsNull(objmap.Remove(new MyKey()));
            Assert.AreEqual(objmap.Get(0), "foobar");
            Assert.AreEqual(objmap.Get(aKey), "value");
        }
예제 #55
0
        public LevelDBBlockchain(string path)
        {
            header_index.Add(GenesisBlock.Hash);
            Slice value;

            db = DB.Open(path);
            if (db.TryGet(ReadOptions.Default, SliceBuilder.Begin(DataEntryPrefix.CFG_Initialized), out value) && value.ToBoolean())
            {
                ReadOptions options = new ReadOptions {
                    FillCache = false
                };
                value = db.Get(options, SliceBuilder.Begin(DataEntryPrefix.SYS_CurrentBlock));
                this.current_block_hash   = new UInt256(value.ToArray().Take(32).ToArray());
                this.current_block_height = BitConverter.ToUInt32(value.ToArray(), 32);
                foreach (Block header in db.Find(options, SliceBuilder.Begin(DataEntryPrefix.DATA_HeaderList), (k, v) =>
                {
                    using (MemoryStream ms = new MemoryStream(v.ToArray(), false))
                        using (BinaryReader r = new BinaryReader(ms))
                        {
                            return(new
                            {
                                Index = BitConverter.ToUInt32(k.ToArray(), 1),
                                Headers = r.ReadSerializableArray <Block>()
                            });
                        }
                }).OrderBy(p => p.Index).SelectMany(p => p.Headers).ToArray())
                {
                    if (header.Hash != GenesisBlock.Hash)
                    {
                        header_chain.Add(header.Hash, header, header.PrevBlock);
                        header_index.Add(header.Hash);
                    }
                    stored_header_count++;
                }
                if (stored_header_count == 0)
                {
                    Dictionary <UInt256, Block> table = db.Find(options, SliceBuilder.Begin(DataEntryPrefix.DATA_Block), (k, v) => Block.FromTrimmedData(v.ToArray(), 0)).ToDictionary(p => p.PrevBlock);
                    for (UInt256 hash = GenesisBlock.Hash; hash != current_block_hash;)
                    {
                        Block header = table[hash];
                        header_chain.Add(header.Hash, header, header.PrevBlock);
                        header_index.Add(header.Hash);
                        hash = header.Hash;
                    }
                }
                else if (current_block_height >= stored_header_count)
                {
                    List <Block> list = new List <Block>();
                    for (UInt256 hash = current_block_hash; hash != header_index[(int)stored_header_count - 1];)
                    {
                        Block header = Block.FromTrimmedData(db.Get(options, SliceBuilder.Begin(DataEntryPrefix.DATA_Block).Add(hash)).ToArray(), 0);
                        list.Add(header);
                        header_index.Insert((int)stored_header_count, hash);
                        hash = header.PrevBlock;
                    }
                    for (int i = list.Count - 1; i >= 0; i--)
                    {
                        header_chain.Add(list[i].Hash, list[i], list[i].PrevBlock);
                    }
                }
                this.current_header_hash = header_index[header_index.Count - 1];
            }
            else
            {
                WriteBatch  batch   = new WriteBatch();
                ReadOptions options = new ReadOptions {
                    FillCache = false
                };
                using (Iterator it = db.NewIterator(options))
                {
                    for (it.SeekToFirst(); it.Valid(); it.Next())
                    {
                        batch.Delete(it.Key());
                    }
                }
                batch.Put(SliceBuilder.Begin(DataEntryPrefix.CFG_Version), 0);
                db.Write(WriteOptions.Default, batch);
                Persist(GenesisBlock);
                db.Put(WriteOptions.Default, SliceBuilder.Begin(DataEntryPrefix.CFG_Initialized), true);
            }
            thread_persistence      = new Thread(PersistBlocks);
            thread_persistence.Name = "LevelDBBlockchain.PersistBlocks";
            thread_persistence.Start();
            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        }
예제 #56
0
 public Iterator EraseSwap(Iterator in_rIter)
 {
     return(new Iterator(AkSoundEnginePINVOKE.CSharp_AkPlaylistArray_EraseSwap(this.swigCPtr, Iterator.getCPtr(in_rIter)), true));
 }
예제 #57
0
        /// <summary>
        /// Compute the intersection of the provided sets. this method is much faster than
        /// computing the intersection manually since it operates directly at the byte level.
        /// </summary>
        public static WAH8DocIdSet Intersect(ICollection <WAH8DocIdSet> docIdSets, int indexInterval)
        {
            switch (docIdSets.Count)
            {
            case 0:
                throw new System.ArgumentException("There must be at least one set to intersect");

            case 1:
                var iter = docIdSets.GetEnumerator();
                iter.MoveNext();
                return(iter.Current);
            }
            // The logic below is similar to ConjunctionScorer
            int numSets = docIdSets.Count;

            Iterator[] iterators = new Iterator[numSets];
            int        i         = 0;

            foreach (WAH8DocIdSet set in docIdSets)
            {
                Iterator it = (Iterator)set.GetIterator();
                iterators[i++] = it;
            }
            Array.Sort(iterators, SERIALIZED_LENGTH_COMPARATOR);
            WordBuilder builder = (WordBuilder)(new WordBuilder()).SetIndexInterval(indexInterval);
            int         wordNum = 0;

            while (true)
            {
                // Advance the least costly iterator first
                iterators[0].AdvanceWord(wordNum);
                wordNum = iterators[0].WordNum;
                if (wordNum == DocIdSetIterator.NO_MORE_DOCS)
                {
                    break;
                }
                byte word = iterators[0].Word;
                for (i = 1; i < numSets; ++i)
                {
                    if (iterators[i].WordNum < wordNum)
                    {
                        iterators[i].AdvanceWord(wordNum);
                    }
                    if (iterators[i].WordNum > wordNum)
                    {
                        wordNum = iterators[i].WordNum;
                        goto mainContinue;
                    }
                    Debug.Assert(iterators[i].WordNum == wordNum);
                    word &= iterators[i].Word;
                    if (word == 0)
                    {
                        // There are common words, but they don't share any bit
                        ++wordNum;
                        goto mainContinue;
                    }
                }
                // Found a common word
                Debug.Assert(word != 0);
                builder.AddWord(wordNum, word);
                ++wordNum;
                mainContinue :;
            }
            //mainBreak:
            return(builder.Build());
        }
예제 #58
0
        public void Start()
        {
            try
            {
                Statistics.getInstance().getStaticInformations();



                int months = Console.Read();
                if (months <= 0)
                {
                    Console.WriteLine("There are 1 female and 1 male newborn rabbits in the coop..");
                }
                else
                {

                    Coop coop = new Coop();
                    coop.getGenderRabbits(Gender.MALE);
                    coop.getGenderRabbits(Gender.FEMALE);

                    for (int month = 0; month <= months;)
                    {
                        if (coop.femaleRabbits.Count > 0)
                        {
                            int newBornFemaleRabbit = 0;
                            int newBornMaleRabbit = 0;
                            foreach (FemaleRabbit femaleRabbit in coop.femaleRabbits)
                            {
                                if (femaleRabbit.getLoseofFertility() > femaleRabbit.getAge() && femaleRabbit.getAge() > 0)
                                {
                                    newBornFemaleRabbit += coop.getNumberofNewbornRabbits()
                                            * coop.getPercentageofRabbitsBorn() / 100;
                                    newBornMaleRabbit += coop.getNumberofNewbornRabbits()
                                            * (100 - coop.getPercentageofRabbitsBorn()) / 100;
                                }
                            }

                            for (int i = 0; i < newBornFemaleRabbit; i++)
                            {
                                coop.getGenderRabbits(Gender.FEMALE);
                            }
                            for (int i = 0; i < newBornMaleRabbit; i++)
                            {
                                coop.getGenderRabbits(Gender.MALE);
                            }
                            Iterator<FemaleRabbit> iterF = coop.femaleRabbits.iterator();
                            while (iterF.hasNext())
                            {
                                FemaleRabbit femaleRabbit = iterF.next();
                                if (femaleRabbit.getAge() >= femaleRabbit.getLifetime())
                                {
                                    iterF.remove();
                                }
                                else
                                {
                                    if (month != months)
                                        femaleRabbit.age += Statistics.timeofPregnancy;
                                }
                            }

                            Iterator<MaleRabbit> iter = coop.maleRabbits.iterator();
                            while (iter.hasNext())
                            {
                                MaleRabbit maleRabbit = iter.next();
                                if (maleRabbit.getAge() >= maleRabbit.getLifetime())
                                {
                                    iter.remove();
                                }
                                else
                                {
                                    if (month != months)
                                        maleRabbit.age += Statistics.timeofPregnancy;
                                }
                            }

                        }
                        month += Statistics.timeofPregnancy;
                    }

                    for (int i = 0; i <= months; i++)
                    {
                        int numberFemale = 0;
                        int numberMale = 0;
                        for (FemaleRabbit femaleRabbit : coop.femaleRabbits)
                        {

                            if (femaleRabbit.getAge() == i)
                            {
                                numberFemale++;
                            }
                        }

                        for (MaleRabbit maleRabbit : coop.maleRabbits)
                        {

                            if (maleRabbit.getAge() == i)
                            {
                                numberMale++;
                            }
                        }

                        System.out.println(i + " months age " + numberFemale + " female " + numberMale + " male rabbits");

                    }

                }

            }
            catch (Exception e)
            {
                System.out.println(e);
            }
        }
예제 #59
0
        /// <summary>
        /// Run example
        /// </summary>
        public void Run()
        {
            // Format matrix output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();

            formatProvider.TextInfo.ListSeparator = " ";

            // Solve next system of linear equations (Ax=b):
            // 5*x + 2*y - 4*z = -7
            // 3*x - 7*y + 6*z = 38
            // 4*x + 1*y + 5*z = 43

            // Create matrix "A" with coefficients
            var matrixA = DenseMatrix.OfArray(new[, ] {
                { 5.00, 2.00, -4.00 }, { 3.00, -7.00, 6.00 }, { 4.00, 1.00, 5.00 }
            });

            Console.WriteLine(@"Matrix 'A' with coefficients");
            Console.WriteLine(matrixA.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create vector "b" with the constant terms.
            var vectorB = new DenseVector(new[] { -7.0, 38.0, 43.0 });

            Console.WriteLine(@"Vector 'b' with the constant terms");
            Console.WriteLine(vectorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Create stop criteriums to monitor an iterative calculation. There are next available stop criteriums:
            // - DivergenceStopCriterium: monitors an iterative calculation for signs of divergence;
            // - FailureStopCriterium: monitors residuals for NaN's;
            // - IterationCountStopCriterium: monitors the numbers of iteration steps;
            // - ResidualStopCriterium: monitors residuals if calculation is considered converged;

            // Stop calculation if 1000 iterations reached during calculation
            var iterationCountStopCriterium = new IterationCountStopCriterium <double>(1000);

            // Stop calculation if residuals are below 1E-10 --> the calculation is considered converged
            var residualStopCriterium = new ResidualStopCriterium(1e-10);

            // Create monitor with defined stop criteriums
            var monitor = new Iterator <double>(new IIterationStopCriterium <double>[] { iterationCountStopCriterium, residualStopCriterium });

            // Create Generalized Product Bi-Conjugate Gradient solver
            var solver = new GpBiCg(monitor);

            // 1. Solve the matrix equation
            var resultX = solver.Solve(matrixA, vectorB);

            Console.WriteLine(@"1. Solve the matrix equation");
            Console.WriteLine();

            // 2. Check solver status of the iterations.
            // Solver has property IterationResult which contains the status of the iteration once the calculation is finished.
            // Possible values are:
            // - CalculationCancelled: calculation was cancelled by the user;
            // - CalculationConverged: calculation has converged to the desired convergence levels;
            // - CalculationDiverged: calculation diverged;
            // - CalculationFailure: calculation has failed for some reason;
            // - CalculationIndetermined: calculation is indetermined, not started or stopped;
            // - CalculationRunning: calculation is running and no results are yet known;
            // - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
            Console.WriteLine(@"2. Solver status of the iterations");
            Console.WriteLine(solver.IterationResult);
            Console.WriteLine();

            // 3. Solution result vector of the matrix equation
            Console.WriteLine(@"3. Solution result vector of the matrix equation");
            Console.WriteLine(resultX.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Verify result. Multiply coefficient matrix "A" by result vector "x"
            var reconstructVecorB = matrixA * resultX;

            Console.WriteLine(@"4. Multiply coefficient matrix 'A' by result vector 'x'");
            Console.WriteLine(reconstructVecorB.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
        /// <summary>
        ///     The function that will be called when the <see cref="colyseusConnection" /> receives a message
        /// </summary>
        /// <param name="bytes">The message as provided from the <see cref="colyseusConnection" /></param>
        protected async void ParseMessage(byte[] bytes)
        {
            byte code = bytes[0];

            if (code == ColyseusProtocol.JOIN_ROOM)
            {
                int offset = 1;

                SerializerId = Encoding.UTF8.GetString(bytes, offset + 1, bytes[offset]);
                offset      += SerializerId.Length + 1;

                if (SerializerId == "schema")
                {
                    try
                    {
                        serializer = new ColyseusSchemaSerializer <T>();
                    }
                    catch (Exception e)
                    {
                        DisplaySerializerErrorHelp(e,
                                                   "Consider using the \"schema-codegen\" and providing the same room state for matchmaking instead of \"" +
                                                   typeof(T).Name + "\"");
                    }
                }
                else if (SerializerId == "fossil-delta")
                {
                    Debug.LogError(
                        "FossilDelta Serialization has been deprecated. It is highly recommended that you update your code to use the Schema Serializer. Otherwise, you must use an earlier version of the Colyseus plugin");
                }
                else
                {
                    try
                    {
                        serializer = (IColyseusSerializer <T>) new ColyseusNoneSerializer();
                    }
                    catch (Exception e)
                    {
                        DisplaySerializerErrorHelp(e,
                                                   "Consider setting state in the server-side using \"this.setState(new " + typeof(T).Name +
                                                   "())\"");
                    }
                }

                if (bytes.Length > offset)
                {
                    serializer.Handshake(bytes, offset);
                }

                OnJoin?.Invoke();

                // Acknowledge JOIN_ROOM
                await colyseusConnection.Send(new[] { ColyseusProtocol.JOIN_ROOM });
            }
            else if (code == ColyseusProtocol.ERROR)
            {
                Iterator it = new Iterator {
                    Offset = 1
                };
                float  errorCode    = Decode.DecodeNumber(bytes, it);
                string errorMessage = Decode.DecodeString(bytes, it);
                OnError?.Invoke((int)errorCode, errorMessage);
            }
            else if (code == ColyseusProtocol.ROOM_DATA_SCHEMA)
            {
                Iterator it = new Iterator {
                    Offset = 1
                };
                float typeId = Decode.DecodeNumber(bytes, it);

                Type          messageType = ColyseusContext.GetInstance().Get(typeId);
                Schema.Schema message     = (Schema.Schema)Activator.CreateInstance(messageType);

                message.Decode(bytes, it);

                IColyseusMessageHandler handler = null;
                OnMessageHandlers.TryGetValue("s" + message.GetType(), out handler);

                if (handler != null)
                {
                    handler.Invoke(message);
                }
                else
                {
                    Debug.LogWarning("room.OnMessage not registered for Schema of type: '" + message.GetType() + "'");
                }
            }
            else if (code == ColyseusProtocol.LEAVE_ROOM)
            {
                await Leave();
            }
            else if (code == ColyseusProtocol.ROOM_STATE)
            {
                Debug.Log("ROOM_STATE");
                SetState(bytes, 1);
            }
            else if (code == ColyseusProtocol.ROOM_STATE_PATCH)
            {
                Patch(bytes, 1);
            }
            else if (code == ColyseusProtocol.ROOM_DATA)
            {
                IColyseusMessageHandler handler = null;
                object type;

                Iterator it = new Iterator {
                    Offset = 1
                };

                if (Decode.NumberCheck(bytes, it))
                {
                    type = Decode.DecodeNumber(bytes, it);
                    OnMessageHandlers.TryGetValue("i" + type, out handler);
                }
                else
                {
                    type = Decode.DecodeString(bytes, it);
                    OnMessageHandlers.TryGetValue(type.ToString(), out handler);
                }

                if (handler != null)
                {
                    //
                    // MsgPack deserialization can be optimized:
                    // https://github.com/deniszykov/msgpack-unity3d/issues/23
                    //
                    object message = bytes.Length > it.Offset
                        ? MsgPack.Deserialize(handler.Type,
                                              new MemoryStream(bytes, it.Offset, bytes.Length - it.Offset, false))
                        : null;

                    handler.Invoke(message);
                }
                else
                {
                    Debug.LogWarning("room.OnMessage not registered for: '" + type + "'");
                }
            }
        }