public PartitionResult CreateFuzzyPartitionWithFixedCenters(PartitionSettings partitionSettings, RenderingSettings renderingSettings)
        {
            _partitionFixedCentersComputer.Init(partitionSettings);

            var muRenderTexture = _partitionFixedCentersComputer.Run(out var psiGridTexture);

            var result = new PartitionResult
            {
                TargetFunctionalValue = CalculateTargetFunctionalValue(partitionSettings, muRenderTexture),
                DualFunctionalValue   = CalculateDualFunctionalValue(partitionSettings, psiGridTexture),
                WorkFinished          = true
            };

            _partitionImageShower.RenderingSettings = renderingSettings;
            _partitionImageShower.CreatePartitionAndShow(partitionSettings, muRenderTexture);

            return(result);
        }
Exemplo n.º 2
0
        public PartitionResultWrapper Partition(LBT lbt, Segment S_l, Segment S_r, PartitionClass P_l, PartitionClass P_r, RelationTreeNode TLEFT, RelationTreeNode BLEFT)
        {
            PartitionResult R = new PartitionResult();

            if (TLEFT != null)
            {
                foreach (Stroke s in TLEFT.strokes)
                {
                    R.TLEFT.strokes.Add(s);
                }
            }
            if (BLEFT != null)
            {
                foreach (Stroke s in BLEFT.strokes)
                {
                    R.BLEFT.strokes.Add(s);
                }
            }

            // Handle no right/left symbol.
            if (S_l == null && S_r == null)
            {
                throw new ArgumentException("Partition:: both passed segments are null.");
            }

            // y-writing-line hack
            if (S_l != null && (S_l.classification[0].symbol == "y" || S_l.classification[0].symbol == "\\log" || S_l.classification[0].symbol == "\\tan"))
            {
                P_l = PartitionClass.Regular;                 // if not already?
                int[] lines = GetCenteredLines(S_l);
                S_l.bb.Top    = lines[0];
                S_l.bb.Bottom = lines[1];
            }

            // Case for no right symbol (and default; symbols at left of current symbol).
            //List< Stroke > SP = S_r == null ? lbt.strokes : lbt.strokes.Where( _s => { if ( _s.aabb.Left < S_r.bb.Left ) { Console.WriteLine( "{0} < {1} (!)", _s.aabb.Left, S_r.bb.Left ); return true; } else { return false; } } ).ToList();
            List <Stroke> SP = new List <Stroke>();

            if (S_r == null)
            {
                SP = lbt.strokes;
            }
            else
            {
                // foreach ( Stroke _s in lbt.strokes ) {
                for (int i = 0; i < lbt.strokes.Count; i++)
                {
                    Stroke _s = lbt.strokes[i];
                    if (_s.aabb.Right /*Left?*/ < S_r.bb.Left)
                    {
                        //Console.WriteLine( "{0} < {1} (!)", _s.aabb.Left, S_r.bb.Left );
                        SP.Add(_s);
                    }
                }
            }

            // Case for no left symbol; switch right to "left" symbol.

            bool noLeft = false;

            if (S_l == null)
            {
                S_l    = S_r;
                SP     = lbt.strokes.Where(_s => _s.aabb.Right < S_r.bb.Left).ToList();
                noLeft = true;
            }

            // HACK.
            bool indexed = S_l != null && (S_l.classification[0].symbol == "\\sum" || S_l.classification[0].symbol == "\\int" ||
                                           S_l.classification[0].symbol == "\\lim");

            foreach (Stroke _s in SP)
            {
                if (S_l != null && !noLeft)
                {
                    bool horOverlap = !(S_l.bb.Right < _s.aabb.Left || _s.aabb.Right < S_l.bb.Left);
                    bool fullContained = S_l.bb.Left <_s.aabb.Left && S_l.bb.Right> _s.aabb.Right &&
                                         S_l.bb.Top <_s.aabb.Top && S_l.bb.Bottom> _s.aabb.Bottom;

                    float midRight = S_l.bb.Top + (S_l.bb.Height / 2);
                    float dtop     = midRight - _s.aabb.Top;
                    float dbottom  = _s.aabb.Bottom - midRight;

                    //float topSpan = Math.Min( Math.Abs( S_l.bb.Top - _s.aabb.Bottom ), Math.Abs( midRight - _s.aabb.Top ) );
                    //float bottomSpan = Math.Min( Math.Abs( S_l.bb.Bottom - _s.aabb.Top ), Math.Abs( midRight - _s.aabb.Bottom ) );

                    // Be lenient here; invalid partitions will be pruned
                    bool added = false;
                    if (P_l == PartitionClass.SquareRoot && fullContained)
                    {
                        R.CONTAINS.strokes.Add(_s);
                        added = true;
                    }
                    else if (/*P_l == PartitionClass.HorLine &&*/ horOverlap)
                    {
                        /*
                         *                      if ( _s.aabb.Bottom <= S_l.bb.Top ) {
                         *                              R.ABOVE.strokes.Add( _s );
                         *                              added = true;
                         *                      } else if ( _s.aabb.Top > S_l.bb.Bottom ) {
                         *                              R.BELOW.strokes.Add( _s );
                         *                              added = true;
                         *                      }
                         */

                        // "less strict" constraints on top/bottom
                        if (_s.aabb.Top < S_l.bb.Top && _s.aabb.Bottom <= S_l.bb.Bottom)
                        {
                            R.ABOVE.strokes.Add(_s);
                            added = true;
                        }
                        else if (_s.aabb.Bottom > S_l.bb.Bottom && _s.aabb.Top >= S_l.bb.Top)
                        {
                            R.BELOW.strokes.Add(_s);
                            added = true;
                        }
                    }
                    else if (dtop > dbottom)
                    {
                        R.SUPER.strokes.Add(_s);
                        added = true;
                    }
                    else
                    {
                        R.SUBSC.strokes.Add(_s);
                        added = true;
                    }
#if DEBUG
                    if (!added)
                    {
                        Console.Error.WriteLine("Stroke ({0}) did not get partitioned in {1}.", _s, S_l);
                    }
#endif
                }
                else
                {
                    // HACK** There is nothing at left. Create TLEFT/BLEFT regions.
                    double midPoint = (S_r.bb.Top + S_r.bb.Bottom) / 2.0;
                    if (_s.aabb.Bottom <= midPoint)
                    {
                        R.TLEFT.strokes.Add(_s);
                    }
                    else if (_s.aabb.Top > midPoint)
                    {
                        R.BLEFT.strokes.Add(_s);
                    }
                }
            }

            // split SUPER/SUBSC by finding maximum gap location
            if (S_l != null && S_r != null)
            {
                float super_gap = MaximumGapLocation(R.SUPER.strokes, S_l, S_r);
                float subsc_gap = MaximumGapLocation(R.SUBSC.strokes, S_l, S_r);

                // super
                foreach (Stroke s in R.SUPER.strokes)
                {
                    if (s.aabb.Left > super_gap)
                    {
                        R.TLEFT.strokes.Add(s);
                    }
                }
                foreach (Stroke s in R.TLEFT.strokes)
                {
                    if (R.SUPER.strokes.Contains(s))
                    {
                        R.SUPER.strokes.Remove(s);
                    }
                }

                // subsc
                foreach (Stroke s in R.SUBSC.strokes)
                {
                    if (s.aabb.Left > subsc_gap)
                    {
                        R.BLEFT.strokes.Add(s);
                    }
                }
                foreach (Stroke s in R.BLEFT.strokes)
                {
                    if (R.SUBSC.strokes.Contains(s))
                    {
                        R.SUBSC.strokes.Remove(s);
                    }
                }
            }

            // if nosupersub, add super/sub to TLEFT/BLEFT
            if (P_l == PartitionClass.HorLine)
            {
                foreach (Stroke s in R.SUPER.strokes)
                {
                    R.TLEFT.strokes.Add(s);
                }
                R.SUPER.strokes.Clear();

                foreach (Stroke s in R.SUBSC.strokes)
                {
                    R.BLEFT.strokes.Add(s);
                }
                R.SUBSC.strokes.Clear();
            }

            // Create LBTs.
            R.ABOVE.lbt    = new LBT(R.ABOVE.strokes, LBT.DefaultAdjacentCriterion);
            R.BELOW.lbt    = new LBT(R.BELOW.strokes, LBT.DefaultAdjacentCriterion);
            R.CONTAINS.lbt = new LBT(R.CONTAINS.strokes, LBT.DefaultAdjacentCriterion);
            R.SUPER.lbt    = new LBT(R.SUPER.strokes, LBT.DefaultAdjacentCriterion);
            R.SUBSC.lbt    = new LBT(R.SUBSC.strokes, LBT.DefaultAdjacentCriterion);
            R.TLEFT.lbt    = new LBT(R.TLEFT.strokes, LBT.DefaultAdjacentCriterion);
            R.BLEFT.lbt    = new LBT(R.BLEFT.strokes, LBT.DefaultAdjacentCriterion);

            // combine above/super/tleft and below/subsc/bleft for horline
            if (indexed)
            {
                if (R.ABOVE.strokes.Count > 0 && (R.SUPER.strokes.Count > 0 || R.TLEFT.strokes.Count > 0))
                {
                    foreach (Stroke s in R.SUPER.strokes)
                    {
                        R.ABOVE.strokes.Add(s);
                    }
                    R.SUPER.strokes.Clear();
                    R.SUPER.lbt = new LBT(R.SUPER.strokes, LBT.DefaultAdjacentCriterion);

                    foreach (Stroke s in R.TLEFT.strokes)
                    {
                        R.ABOVE.strokes.Add(s);
                    }
                    R.TLEFT.strokes.Clear();
                    R.TLEFT.lbt = new LBT(R.TLEFT.strokes, LBT.DefaultAdjacentCriterion);

                    R.ABOVE.strokes.Sort((s1, s2) => int.Parse(s1.stroke_id) - int.Parse(s2.stroke_id));
                    R.ABOVE.lbt = new LBT(R.ABOVE.strokes, LBT.DefaultAdjacentCriterion);
                }
                if (R.BELOW.strokes.Count > 0 && (R.SUBSC.strokes.Count > 0 || R.BLEFT.strokes.Count > 0))
                {
                    foreach (Stroke s in R.SUBSC.strokes)
                    {
                        R.BELOW.strokes.Add(s);
                    }
                    R.SUBSC.strokes.Clear();
                    R.SUBSC.lbt = new LBT(R.SUBSC.strokes, LBT.DefaultAdjacentCriterion);

                    foreach (Stroke s in R.BLEFT.strokes)
                    {
                        R.BELOW.strokes.Add(s);
                    }
                    R.BLEFT.strokes.Clear();
                    R.BLEFT.lbt = new LBT(R.BLEFT.strokes, LBT.DefaultAdjacentCriterion);

                    R.BELOW.strokes.Sort((s1, s2) => int.Parse(s1.stroke_id) - int.Parse(s2.stroke_id));
                    R.BELOW.lbt = new LBT(R.BELOW.strokes, LBT.DefaultAdjacentCriterion);
                }
            }


            //Console.WriteLine("SUPER STROKES: {0}",R.SUPER.lbt.strokes.Count);

            return(new PartitionResultWrapper(R, UpdateLBT(new Segment {
                strokes = SP
            }, lbt)));
            //lbt = UpdateLBT( new Segment { strokes = SP }, lbt ) };
        }