线性差值法结构类(面向对象的方式)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using User1.Valuation.Holworth.EngineInfrastructure;

namespace ConsoleApplication7
{
    public enum PointState
    {
        Inner = 0,//定义域的点
        Mid = 1,//未超出定义域的点
        LeftOuter = 2,//超出左侧
        RightOuter = 3//超出右侧
    }
    public class Point
    {
        public Point Left;
        public Point Right;
        public double x;
        public double y;

        public PointState state;
    }
    class Program
    {
        static void Main(string[] args)
        {
          
            List<double> list1 = new List<double>();
            List<double> list2 = new List<double>();
            for (int i = 0; i < 10; i++)
            {
                byte[] buffer = Guid.NewGuid().ToByteArray();
                int iSeed = BitConverter.ToInt32(buffer, 0);
                Random r = new Random(iSeed);
                list1.Add(r.Next(1,100));
                list2.Add(r.Next(1,100));
            }


            double[] xarr;

            double[] yarr;

            xarr = list1.ToArray();
            yarr = list2.ToArray();
            //求解的点
            double[] x1arr = new double[] { 1, 2, 3, 4, 6, 8, 11, 13, 14, 16, 17 };
            double[] y1arr;
            Dictionary<double, Point> pointDictionary = new Dictionary<double, Point>();
            int m = 1* 1;
            DateTime t1 = DateTime.Now;
            for (int i = 0; i < m; i++)
            {
                pointDictionary = LineDifferenceMethod(xarr, yarr, x1arr,out y1arr, true);
            }
            DateTime t2 = DateTime.Now;
            Console.WriteLine("勇士:"+t2.Subtract(t1).TotalSeconds);

            foreach (var item in pointDictionary)
            {
                Console.WriteLine(item.Key + "\t" + item.Value.y);
            }


            Console.Read();
        }
        /// <summary>
        /// 线性差值法
        /// </summary>
        /// <param name="xarr">原始数据x轴</param>
        /// <param name="yarr">原始数据y轴</param>
        /// <param name="x1arr">求解的x轴的点的数组</param>
        /// <param name="extension">边缘点是否使用斜率延伸</param>
        /// <returns></returns>
        public static Dictionary<double, Point> LineDifferenceMethod(double[] xarr, double[] yarr, double[] x1arr,out double[] y1arr, bool extension = false)
        {
          
            Dictionary<double, Point> pointDict = new Dictionary<double, Point>();
            for (int i = 0; i < xarr.Length; i++)
            {
                Point p = new Point();
                p.x = xarr[i];
                p.y = yarr[i];
                p.state = PointState.Inner;
                pointDict[p.x] = p;
            }
            for (int i = 0; i < x1arr.Length; i++)
            {
                if (pointDict.ContainsKey(x1arr[i]))
                {
                    continue;
                }
                Point p = new Point();
                p.x = x1arr[i];
                p.state = PointState.Mid;//默认值
                pointDict[p.x] = p;
            }
            var orderbylist = pointDict.OrderBy(p => p.Key).ToList();
            pointDict=orderbylist.ToDictionary(p=>p.Key,p=>p.Value);
            var oriList = orderbylist.Where(p => p.Value.state== PointState.Inner).Select(p=>p.Value).ToArray();
            Point firstPoint = oriList[0]; ;
            Point lastPoint = oriList[oriList.Length-1];


            if (xarr.Length== 1)
            {
                for (int i = 0; i < x1arr.Length; i++)
                {
                    Point p = new Point();
                    p.x = x1arr[i];
                    p.y = yarr[0];
                    if (p.x != xarr[0])
                    {
                        if (p.x < xarr[0])
                        {
                            p.state = PointState.LeftOuter;
                        }
                        else if (p.x > xarr[0])
                        {
                            p.state = PointState.RightOuter;
                        }
                    }

                }
                y1arr = new double[x1arr.Length];
                for (int i = 0; i < x1arr.Length; i++)
                {
                    y1arr[i] = yarr[0];
                    pointDict[x1arr[i]].y = y1arr[i];
                }
                return pointDict;
            }

            

            for (int i = 0; i < x1arr.Length; i++)
            {
               
                double qx = x1arr[i];
                Point p = pointDict[qx];
                if (qx < firstPoint.x)
                {
                    p.state = PointState.LeftOuter;

                }
                else if (qx > lastPoint.x)
                {
                    p.state = PointState.RightOuter;
                }
                else if (pointDict.ContainsKey(qx))
                {
                    //内部点不用求了
                    p = pointDict[qx];
                    continue;
                }
                else
                {
                    p.state = PointState.Mid;
                }

            }
            var points = pointDict.Values.ToArray();

            for (int i = 0; i < points.Length; i++)
            {

                Point p = points[i];
                if (i == 0)
                {
                    p.Left = null;
                    if (points.Length > 1)
                    {
                        p.Right = points[i + 1];
                    }
                    else
                    {
                        p.Right = null;
                    }

                }
                else if (i == points.Length - 1)
                {
                    p.Right = null;
                    if (points.Length > 1)
                    {
                        p.Left = points[i - 1];
                    }
                    else
                    {
                        p.Right = null;
                    }
                }
                else if (i > 0 && i < points.Length - 1)
                {
                    p.Left = points[i - 1];
                    p.Right = points[i + 1];
                }

            }
            //foreach (var item in points)
            for(int i=0;i<points.Length;i++)
            {
                var item = points[i];
                if (item.state == PointState.Mid)
                {
                    var right = item.Right;
                    var left = item.Left;
                    AdjustLeftRight(ref right, ref left, item);

                }
                else if (item.state == PointState.LeftOuter)
                {

                    if (!extension)
                    {
                        item.y = firstPoint.y;
                    }
                    else
                    {
                        var right = firstPoint.Right;
                        var left = firstPoint;
                        AdjustLeftRight(ref right, ref left, item);



                    }
                }
                else if (item.state == PointState.RightOuter)
                {
                    if (!extension)
                    {
                        item.y = lastPoint.y;
                    }
                    else
                    {
                        var right = lastPoint;
                        var left = lastPoint.Left;
                        AdjustLeftRight(ref right, ref left, item);


                    }
                }
            }

            y1arr = pointDict.Where(p => x1arr.Contains(p.Key)).Select(x => x.Value.y).ToArray();
            return pointDict;

        }

        private static void AdjustLeftRight(ref Point right, ref Point left, Point item)
        {
            while (right.state != PointState.Inner)
            {
                right = right.Right;
            }
            while (left.state != PointState.Inner)
            {
                left = left.Left;
            }
            double k = (right.y - left.y) / (right.x - left.x);//斜率
            item.y = left.y + k * (item.x - left.x);
        }
    }
}

 

posted on 2018-06-29 00:23  听哥哥的话  阅读(384)  评论(0编辑  收藏  举报

导航