/// <summary>
 /// Creates an instantiated factor in this graph, with neighborIndices representing the neighbor variables by integer
 /// index.
 /// </summary>
 /// <param name="featureTable">the feature table to use to drive the value of the factor</param>
 /// <param name="neighborIndices">the indices of the neighboring variables, in order</param>
 /// <returns>a reference to the created factor. This can be safely ignored, as the factor is already saved in the model</returns>
 public virtual GraphicalModel.Factor AddFactor(ConcatVectorTable featureTable, int[] neighborIndices)
 {
     System.Diagnostics.Debug.Assert((featureTable.GetDimensions().Length == neighborIndices.Length));
     GraphicalModel.Factor factor = new GraphicalModel.Factor(featureTable, neighborIndices);
     factors.Add(factor);
     return(factor);
 }
 /// <summary>Duplicates this factor.</summary>
 /// <returns>a copy of the factor</returns>
 public virtual GraphicalModel.Factor CloneFactor()
 {
     GraphicalModel.Factor clone = new GraphicalModel.Factor();
     clone.neigborIndices = neigborIndices.MemberwiseClone();
     clone.featuresTable  = featuresTable.CloneTable();
     clone.metaData.PutAll(metaData);
     return(clone);
 }
 public static GraphicalModel.Factor ReadFromProto(GraphicalModelProto.Factor proto)
 {
     GraphicalModel.Factor factor = new GraphicalModel.Factor();
     factor.featuresTable  = ConcatVectorTable.ReadFromProto(proto.GetFeaturesTable());
     factor.metaData       = GraphicalModel.ReadMetaDataFromProto(proto.GetMetaData());
     factor.neigborIndices = new int[proto.GetNeighborCount()];
     for (int i = 0; i < factor.neigborIndices.Length; i++)
     {
         factor.neigborIndices[i] = proto.GetNeighbor(i);
     }
     return(factor);
 }
        /// <summary>
        /// Check that two models are deeply value-equivalent, down to the concat vectors inside the factor tables, within
        /// some tolerance.
        /// </summary>
        /// <remarks>
        /// Check that two models are deeply value-equivalent, down to the concat vectors inside the factor tables, within
        /// some tolerance. Mostly useful for testing.
        /// </remarks>
        /// <param name="other">the graphical model to compare against.</param>
        /// <param name="tolerance">the tolerance to accept when comparing concat vectors for value equality.</param>
        /// <returns>whether the two models are tolerance equivalent</returns>
        public virtual bool ValueEquals(GraphicalModel other, double tolerance)
        {
            if (!modelMetaData.Equals(other.modelMetaData))
            {
                return(false);
            }
            if (!variableMetaData.Equals(other.variableMetaData))
            {
                return(false);
            }
            // compare factor sets for equality
            ICollection <GraphicalModel.Factor> remaining = new HashSet <GraphicalModel.Factor>();

            Sharpen.Collections.AddAll(remaining, factors);
            foreach (GraphicalModel.Factor otherFactor in other.factors)
            {
                GraphicalModel.Factor match = null;
                foreach (GraphicalModel.Factor factor in remaining)
                {
                    if (factor.ValueEquals(otherFactor, tolerance))
                    {
                        match = factor;
                        break;
                    }
                }
                if (match == null)
                {
                    return(false);
                }
                else
                {
                    remaining.Remove(match);
                }
            }
            return(remaining.Count <= 0);
        }
 /// <summary>Does a deep comparison, using equality with tolerance checks against the vector table of values.</summary>
 /// <param name="other">the factor to compare to</param>
 /// <param name="tolerance">the tolerance to accept in differences</param>
 /// <returns>whether the two factors are within tolerance of one another</returns>
 public virtual bool ValueEquals(GraphicalModel.Factor other, double tolerance)
 {
     return(Arrays.Equals(neigborIndices, other.neigborIndices) && metaData.Equals(other.metaData) && featuresTable.ValueEquals(other.featuresTable, tolerance));
 }