public void ApplyWithOnePoint()
        {
            var sut = new MembershipFunction{ { 42, 1 } };

            Assert.AreEqual(1, sut.Apply(42.0));
            // The membership value of the one point exists everywhere
            Assert.AreEqual(1, sut.Apply(0));
            Assert.AreEqual(1, sut.Apply(1701));
        }
        public void Apply_With_Triangle_2()
        {
            var msf = new MembershipFunction { { -7, 0 }, { -5, 1 }, { 0, 0 } };

            var sut = new MinMsfScalingStrategy();

            var result = sut.Apply(msf, 0.6);

            Assert.AreEqual(4, result.Count);
            Assert.AreEqual(0, msf.Apply(-7), 0.000000000001);
            Assert.AreEqual(0.6, msf.Apply(-5.8), 0.000000000001);
            Assert.AreEqual(0.6, msf.Apply(-3), 0.000000000001);
            Assert.AreEqual(0, msf.Apply(0), 0.000000000001);
        }
        private MembershipFunction combine(MembershipFunction first, MembershipFunction second)
        {
            if (!first.Any())
                return second;
            if (!second.Any())
                return first;


            var scanPoints = new List<double>();
            scanPoints.AddRange(first.Keys);
            foreach (var key in second.Keys.Where(key => !scanPoints.Contains(key)))
                scanPoints.Add(key);
            scanPoints.Sort();



            var result = new MembershipFunction();
            foreach (var scanPoint in scanPoints)
            {
                var valueFirst = first.Apply(scanPoint);
                var valueSecond = second.Apply(scanPoint);

                result.Add(scanPoint, valueFirst + valueSecond);
            }

            return result.ClearUp();
        }
        public void ApplyForComplex()
        {
            var sut = new MembershipFunction { { 0, 0.5 }, { 1, 0 }, { 2, 0.5 }, { 3, 0.5 }, { 5, 1 }, { 6, 0.5 } };

            Assert.AreEqual( 0.5, sut.Apply(-1));
            Assert.AreEqual( 0.5, sut.Apply(0));
            Assert.AreEqual(0.25, sut.Apply(1.5));
            Assert.AreEqual( 0.5, sut.Apply(2));
            Assert.AreEqual( 0.5, sut.Apply(3));
            Assert.AreEqual(0.75, sut.Apply(4));
            Assert.AreEqual(   1, sut.Apply(5));
            Assert.AreEqual( 0.5, sut.Apply(6));
            Assert.AreEqual( 0.5, sut.Apply(7));
        }
        public void ApplyForTriangle()
        {
            var sut = new MembershipFunction {{1, 0}, {3, 1}, {5, 0}};

            Assert.AreEqual(0.0, sut.Apply(0));
            Assert.AreEqual(0.0, sut.Apply(1));
            Assert.AreEqual(0.5, sut.Apply(2));
            Assert.AreEqual(1.0, sut.Apply(3));
            Assert.AreEqual(0.5, sut.Apply(4));
            Assert.AreEqual(0.0, sut.Apply(5));
            Assert.AreEqual(0.0, sut.Apply(6));
        }
        private static MembershipFunction combine(MembershipFunction first, MembershipFunction second)
        {
            if (!first.Any())
                return second;
            if (!second.Any())
                return first;
            
            var scanPoints = getScanPoints(first, second);
            
            var result = new MembershipFunction();
            for (var i = 0; i < scanPoints.Count; i++)
            {
                var scanPoint = scanPoints[i];

                var valueFirst = first.Apply(scanPoint);
                var valueSecond = second.Apply(scanPoint);

                result.Add(scanPoint, Math.Max(valueFirst, valueSecond));
                
                // Check if there is an intersection between this scan point and the next
                // and add it to the list of scan points:
                var nextKeyFirst = getNextKey(first, scanPoint);
                var nextKeySecond = getNextKey(second, scanPoint);
                if (nextKeyFirst.HasValue && nextKeySecond.HasValue)
                {
                    var nextValueFirst = first[nextKeyFirst.Value];
                    var nextValueSecond = second[nextKeySecond.Value];

                    if (valueFirst >= valueSecond && nextValueFirst < nextValueSecond ||
                        valueFirst < valueSecond && nextValueFirst >= nextValueSecond)
                    {
                        var lineFirst = new LineSegment(new Point(scanPoint, valueFirst),
                            new Point(nextKeyFirst.Value, nextValueFirst));
                        var lineSecond = new LineSegment(new Point(scanPoint, valueSecond),
                            new Point(nextKeySecond.Value, nextValueSecond));

                        var intersection = lineFirst.Intersect(lineSecond);
                        if (intersection != null && !scanPoints.Contains(intersection.X) && intersection.X > scanPoint)
                            scanPoints.Insert(i + 1, intersection.X);
                    }
                }
            }

            return result.ClearUp();
        }
        public void NoPointsMeansAlwaysZero()
        {
            var sut = new MembershipFunction();

            Assert.AreEqual(0, sut.Apply(42.0));
        }