internal void Add(Block block)
 {
     block.VectorIndex = Vector.Count;
     Vector.Add(block);
     //Debug_AssertConsistency();
     Debug.Assert(Vector[block.VectorIndex] == block, "Inconsistent block.VectorIndex");
 }
        internal bool FilterBlock(Block blockToFilter)
        {
            // Note: The cache does not try to retain strict accordance with highest violation.
            // Doing so lowers the hit rate, probably because if LastModifiedBlock has enough variables,
            // then it has enough high violations to flush all other blocks out of the cache, and
            // thus the next call to FilterBlock removes all for the current block (which per the following
            // paragraph results in calling SearchAllConstraints).  As it turns out, it doesn't
            // really matter what order we process the constraints in, other than the perf benefit of
            // doing the largest violations first, so using the max violation in LastModifiedBlock in this
            // situation seems to be good enough to win the tradeoff.
            //
            // If it becomes necessary to maintain strict "cache always contains the highest violations"
            // compliance, then we would have to return false if the filtering removed all elements of
            // the cache, because then we wouldn't know if there were any non-blockToFilter-related constraints
            // with a higher violation (currently we return true in that case because it is good enough to know
            // there is a good chance that this is true).  Also, SearchViolationCache would need a verification in
            // at least VERIFY mode to verify there are no higher violations in allConstraints.

            // Iterate in reverse to remove constraints belonging to LastModifiedBlock.
            // Note:  Enumerators and .Where are not used because they are much slower.
            LowViolation = double.MaxValue;
            bool fRet = this.numConstraints > 0;
            for (int ii = this.numConstraints - 1; ii >= 0; --ii)
            {
                var constraint = this.constraints[ii];

                // Also remove any constraint that may have been activated by MergeBlocks or marked unsatisfiable
                // by Block.Expand.
                if ((constraint.Left.Block == blockToFilter) || (constraint.Right.Block == blockToFilter) || constraint.IsActive || constraint.IsUnsatisfiable)
                {
                    // If there are any items after this one, then they are ones we want to keep,
                    // so swap in the last one in the array before decrementing the count.
                    if (ii < (this.numConstraints - 1))
                    {
                        this.constraints[ii] = this.constraints[this.numConstraints - 1];
                    }
                    --this.numConstraints;
                }
                else
                {
#if Inline_Violation
                    double violation = constraint.Violation;      // Inline_Violation
#else  // Inline_Violation
                    double violation = (constraint.Left.ActualPos * constraint.Left.Scale)
                                        + constraint.Gap
                                        - (constraint.Right.ActualPos * constraint.Right.Scale);
                    Debug.Assert(constraint.Violation == violation, "LeftConstraints: constraint.Violation must == violation");
#endif // Inline_Violation
                    if (violation < LowViolation)
                    {
                        LowViolation = violation;
                    }
                }
            }
            if (0 == this.numConstraints)
            {
                LowViolation = 0.0;
            }
            return fRet;
        }
 internal void Remove(Block block)
 {
     Debug.Assert(Vector[block.VectorIndex] == block, "Inconsistent block.VectorIndex");
     Block swapBlock = Vector[Vector.Count - 1];
     Vector[block.VectorIndex] = swapBlock;
     swapBlock.VectorIndex = block.VectorIndex;
     Vector.RemoveAt(Vector.Count - 1);
     //Debug_AssertConsistency();
     Debug.Assert((0 == Vector.Count) || (block == swapBlock) || (Vector[swapBlock.VectorIndex] == swapBlock),
             "Inconsistent swapBlock.VectorIndex");
     Debug.Assert((0 == Vector.Count) || (Vector[Vector.Count - 1].VectorIndex == (Vector.Count - 1)),
             "Inconsistent finalBlock.VectorIndex");
 }
        private bool Project()
        {
            if (0 == this.numberOfConstraints)
            {
                // We are here for the neighbours-only case.
                return false;
            }

            // Get the maximum violation (the Constraint with the biggest difference between the
            // required gap between its two variables vs. their actual relative positions).
            // If there is no violation, we're done (although SplitBlocks may change things so
            // we have to go again).
            this.violationCache.Clear();
            this.lastModifiedBlock = null;
            bool useViolationCache = this.allBlocks.Count > this.violationCacheMinBlockCutoff;

            // The first iteration gets the first violated constraint.
            int cIterations = 1;

            double maxViolation;
            Constraint maxViolatedConstraint = GetMaxViolatedConstraint(out maxViolation, useViolationCache);
            if (null == maxViolatedConstraint)
            {
#if VERBOSE
                Console.WriteLine("Project() found no violations");
#endif // VERBOSE
                return false;
            }

            // We have at least one violation, so process them until there are no more.
            while (null != maxViolatedConstraint)
            {
                Debug.Assert(!maxViolatedConstraint.IsUnsatisfiable, "maxViolatedConstraint should not be unsatisfiable");
                Debug.Assert(!maxViolatedConstraint.IsEquality, "maxViolatedConstraint should not be equality");
#if VERBOSE
                Console.WriteLine("MaxVio: {0}", maxViolatedConstraint);

                // Write a line in satisfy_inc format to compare:
                // most violated is: (45=9.73427)+3<=(51=0.456531)(-12.2777) [chop off lm as it's uninitialized in satisfy_inc output]
                Console.WriteLine("  most violated is: ({0}={1:F6})+{2:F0}<=({3}={4:F6})({5:F6})",
                                maxViolatedConstraint.Left.Name, maxViolatedConstraint.Left.ActualPos, maxViolatedConstraint.Gap,
                                maxViolatedConstraint.Right.Name, maxViolatedConstraint.Right.ActualPos, maxViolatedConstraint.Violation);
#endif // VERBOSE

                // Perf note: Variables (and Blocks) use the default Object.Equals implementation, which is
                // simply ReferenceEquals for reference types.
                if (maxViolatedConstraint.Left.Block == maxViolatedConstraint.Right.Block)
                {
                    maxViolatedConstraint.Left.Block.Expand(maxViolatedConstraint);
                    if (maxViolatedConstraint.IsUnsatisfiable)
                    {
                        this.violationCache.Clear();   // We're confusing the lineage of lastModifiedBlock
                    }
                    this.lastModifiedBlock = maxViolatedConstraint.Left.Block;
                }
                else
                {
                    // The variables are in different blocks so merge the blocks.
                    this.lastModifiedBlock = MergeBlocks(maxViolatedConstraint);
                }
#if VERBOSE
                DumpCost();
#endif // VERBOSE

                // Note that aborting here does not guarantee a feasible state.
                if (this.solverParams.InnerProjectIterationsLimit > 0)
                {
                    if (cIterations >= this.solverParams.InnerProjectIterationsLimit)
                    {
#if VERBOSE
                        Console.WriteLine("PostProject aborting due to max inner iterations: max {0}",
                                        solverParams.InnerProjectIterationsLimit);
#endif // VERBOSE
                        this.solverSolution.InnerProjectIterationsLimitExceeded = true;
                        break;
                    }
                }

                // Now we've potentially changed one or many variables' positions so recalculate the max violation.
                useViolationCache = this.allBlocks.Count > this.violationCacheMinBlockCutoff;
                if (!useViolationCache)
                {
                    this.violationCache.Clear();
                }
                ++cIterations;
                maxViolatedConstraint = GetMaxViolatedConstraint(out maxViolation, useViolationCache);
            } // endwhile violations exist

            this.solverSolution.InnerProjectIterationsTotal += cIterations;
            if (this.solverSolution.MaxInnerProjectIterations < cIterations)
            {
                this.solverSolution.MaxInnerProjectIterations = cIterations;
            }
            if (this.solverSolution.MinInnerProjectIterations > cIterations)
            {
                this.solverSolution.MinInnerProjectIterations = cIterations;
            }

            // If we got here, we had at least one violation.
            this.allConstraints.Debug_AssertConsistency();
            return true;
        } // end Project()
        private void ReinitializeBlocks()
        {
            // For Qpsc we want to discard the previous block structure, because it did not consider
            // neighbors, and the gradient may want to pull things in an entirely different way.
            // We must also do this for a re-Solve that updated the gap of an equality constraint.
            var oldBlocks = this.allBlocks.Vector.ToArray();
            this.allBlocks.Vector.Clear();
#if VERIFY || VERBOSE
            this.nextNewBlockOrdinal = 0;
#endif // VERIFY || VERBOSE

            foreach (Block oldBlock in oldBlocks)
            {
                foreach (Variable variable in oldBlock.Variables)
                {
                    variable.Reinitialize();
                    var newBlock = new Block(variable, this.allConstraints
#if VERIFY || VERBOSE
                                            , ref this.nextNewBlockOrdinal
#endif // VERIFY || VERBOSE
                        );
                    this.allBlocks.Add(newBlock);
                }
            }

            this.allConstraints.Reinitialize();
            this.violationCache.Clear();
        }
        /// <summary>
        /// Add a Variable (for example, wrapping a node on one axis of the graph) to the Solver.
        /// </summary>
        /// <param name="userData">a tag or other user data - can be null</param>
        /// <param name="desiredPos">The position of the variable, such as the coordinate of a node along one axis.</param>
        /// <param name="weight">The weight of the variable (makes it less likely to move if the weight is high).</param>
        /// <param name="scale">The scale of the variable, for improving convergence.</param>
        /// <returns>The created variable</returns>
        public Variable AddVariable(Object userData, double desiredPos, double weight, double scale)
        {
            // @@DCR "Incremental Solving": For now we disallow this; if we support it, we'll need to
            // retain loadedVariablesAndConstraintLists, store up the added Variables (TryGetValue and if that fails add 
            // the existing variable, then iterate through variables with new Constraints and replace the arrays.
            // Also remember to check for emptyConstraintList - don't add to it.
            if (!this.allConstraints.IsEmpty)
            {
                throw new InvalidOperationException(
#if DEBUG
                        "Cannot add Variables or Constraints once Solve() has been called"
#endif // DEBUG
                    );
            }

            var varNew = new Variable(this.nextVariableOrdinal++, userData, desiredPos, weight, scale);
            var block = new Block(varNew, this.allConstraints
#if VERIFY || VERBOSE
                                , ref this.nextNewBlockOrdinal
#endif // VERIFY || VERBOSE
                );
            varNew.Block = block;
            this.allBlocks.Add(block);
            ++this.numberOfVariables;

            // Initialize the variable in the dictionary with a null list and zero left constraints.
            this.loadedVariablesAndConstraintLists[varNew] = new ConstraintListForVariable(new List<Constraint>(), 0);
            return varNew;
        } // end AddVariable()
        internal Block SplitOnConstraint(Constraint constraintToSplit
#if VERIFY || VERBOSE
                                        , ref uint blockId
#endif // VERIFY || VERBOSE
            )
        {
            // We have a split point.  Remove that constraint from our active list and transfer it and all
            // variables to its right to a new block.  As mentioned above, all variables and associated
            // constraints in the block are active, and the block split and recalc of reference positions
            // doesn't change the actual positions of any variables.
            this.allConstraints.DeactivateConstraint(constraintToSplit);
            var newSplitBlock = new Block(null, this.allConstraints
#if VERIFY || VERBOSE
                                        , ref blockId
#endif // VERIFY || VERBOSE
                );

            // Transfer the connected variables.  This has the side-effect of moving the associated active
            // constraints as well (because they are carried in the variables' LeftConstraints).
            // This must include not only minLagrangianConstraint.Right and those to its right, but also
            // those to its left that are connected to it by active constraints - because connected variables
            // must be within a single a block.  Since we are splitting the constraint, there will be at least
            // one variable (minLagrangianConstraint.Left) in the current block when we're done.  Because the active
            // constraints form a tree, we won't have a situation where minLagrangianConstraint.Left is
            // also the .Right of a constraint of a variable to the left of varRight.
            // minLagrangianConstraint.Left is "already evaluated" because we don't want the path evaluation to
            // back up to it (because we're splitting minLagrangianConstraint by deactivating it).
            this.DebugVerifyBlockConnectivity();
            this.TransferConnectedVariables(newSplitBlock, constraintToSplit.Right, constraintToSplit.Left);
            if (newSplitBlock.Variables.Count > 0)
            {
                // We may have removed the first variable so fully recalculate the reference position.
                this.UpdateReferencePos();

                // The new block's sums were not updated as its variables were added directly to its
                // variables list, so fully recalculate.
                newSplitBlock.UpdateReferencePos();

                this.DebugVerifyBlockConnectivity();
                newSplitBlock.DebugVerifyBlockConnectivity();

#if VERBOSE
                Console.WriteLine("Block.Split Result: {0} {1}", this, newSplitBlock);
                Console.WriteLine("Old block: {0}", this);
                this.DumpState(null /* no prefix */);
                Console.WriteLine("New block: {0}", newSplitBlock);
                newSplitBlock.DumpState(null /* no prefix */);
#endif // VERBOSE
            }
            else
            {
                // If there were unsatisfiable constraints, we may have tried to transfer all variables;
                // in that case we simply ignored the transfer operation and left all variables in 'this' block.
                // Return NULL so Solver.SplitBlocks knows we didn't split.
                newSplitBlock = null;
#if VERBOSE
                Console.WriteLine("Block.Split Result: all variables would be moved, so skipping");
                this.DumpState(null /* no prefix */);
#endif // VERBOSE
            }

            return newSplitBlock;
        } // end Split()
        internal void Debug_PostMerge(Block blockFrom)
        {
#if DEBUG
            // If blockFrom's DfDv-cycle detection value was higher than ours, we need to set ours to
            // that value, to avoid running into stale values.
            if (blockFrom.idDfDv > this.idDfDv)
            {
                this.idDfDv = blockFrom.idDfDv;
            }
#endif // DEBUG
        }
        void TransferConnectedVariables(Block newSplitBlock, Variable varToEval, Variable varDoneEval)
        {
            GetConnectedVariables(newSplitBlock.Variables, varToEval, varDoneEval);
            int numVarsToMove = newSplitBlock.Variables.Count;                       // cache for perf

            // The constraints transferred to the new block need to have any stale cycle-detection values cleared out.
            newSplitBlock.Debug_ClearDfDv(true /* forceFull */);

            // Avoid the creation of an inner loop on List<T>.Remove (which does linear scan and shift
            // to preserve the order of members).  We don't care about variable ordering within the block
            // so we can just repeatedly swap in the end one over whichever we're removing.
            for (int moveIndex = 0; moveIndex < numVarsToMove; ++moveIndex)
            {
                newSplitBlock.Variables[moveIndex].Block = newSplitBlock;
            }

            // Now iterate from the end and swap in the last one we'll keep over the ones we'll remove.
            int lastKeepIndex = this.Variables.Count - 1;
            for (int currentIndex = this.Variables.Count - 1; currentIndex >= 0; --currentIndex)
            {
                Variable currentVariable = this.Variables[currentIndex];
                if (currentVariable.Block == newSplitBlock)
                {
                    if (currentIndex < lastKeepIndex)
                    {
                        // Swap in the one from the end.
                        this.Variables[currentIndex] = this.Variables[lastKeepIndex];
                    }
                    --lastKeepIndex;
                }
            } // end for each var to keep

            // Now remove the end slots we're not keeping.  lastKeepIndex is -1 if we are removing all variables.
            Debug.Assert(numVarsToMove == this.Variables.Count - lastKeepIndex - 1, "variable should not be found twice (probable cycle-detection problem");
            this.Variables.RemoveRange(lastKeepIndex + 1, this.Variables.Count - lastKeepIndex - 1);

            if (0 == this.Variables.Count)
            {
                // This is probably due to unsatisfiable constraints; we've transferred all the variables,
                // so just don't split at all; move the variables back into the current block rather than
                // leaving an empty block in the list.  Caller will detect the empty newSplitBlock and ignore it.
                for (int moveIndex = 0; moveIndex < numVarsToMove; ++moveIndex)
                {
                    var variableToMove = newSplitBlock.Variables[moveIndex];
                    this.Variables.Add(variableToMove);
                    variableToMove.Block = this;
                }
                newSplitBlock.Variables.Clear();
            }
        } // end TransferConnectedVariables()