我是靠谱客的博主 迷人大树,最近开发中收集的这篇文章主要介绍三维度双线性插值,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.最近参与两个界面项目的制作,主要负责底层算法逻辑
2.任务一可分解为一个算法题。
水包温升计算:给定一些离散的仿真数据,希望得到连续的数据,具体而言是一个三维线性插值。
输入:
B=[4 10]
H=[5 8]
Q=[8 12]
其中B为水包内流道高度(mm),H为水包内流道与散热面距离(mm),Q为水流量(L/min),输出水包最高温度。
输出:
需要最终能在程序中输入B在5至8mm、H在4至10mm以及流量Q在8至12L/min内的任意一组数值能得到一个最大温升的结果。其中最大温升为输出水包的最高温度减去40℃。

在这里插入图片描述
双线性插值算法如下
采用的是二分查找,对每一维数据B、H、Q,在其输入区间的任意处都有对应的水包温度,大体思路是采用双线性插值进行处理。

InterAlgorithm类
实现单维双线性插值
首先看binarySearch()函数,对输入的key值进行二分查找,找到其对应数值的在数组中索引区间[index,index+1],依据此找到key值对应的Xnear,Ynear,Xnear即为key值所在所在的区间,Ynear为key对应数值所在的区间。最后调用双线性插值getValue()函数实现插值计算。

 public class InterAlgorithm
    {

        /// <summary>
        /// 计算插值结果,克服二分查找右区间端点无法插值
        /// </summary>
        /// <param name="x_Values"></param>
        /// <param name="y_Values"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static double Compute(double[] x_Values, double[] y_Values, double key)
        {
            int index = binarySearch(x_Values, key);
            double[] Xnear = { };//key隶属区间
            double[] Ynear = { };//key对应的value的隶属区间
            if (index == -1)
            {
                throw new IndexOutOfRangeException("超过插值范围");
            }

            if (index == x_Values.Length-1)
            {
                double t = 0;
                t = y_Values[index];
             return Math.Round(t,3);
            }

  
            Xnear = new double[2] { x_Values[index], x_Values[index+1] };
            Ynear = new double[2] { y_Values[index], y_Values[index+1] };
            return Math.Round(getValue(Xnear, Ynear, key), 3);
        }
        /// <summary>
        /// 通过key值索引获取的x_map,y_map;计算单维线性插值结果
        /// </summary>
        /// <param name="x_map"></param>
        /// <param name="y_map"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private static double getValue(double[] x_map, double[] y_map, double key)
        {
            double x_Avg = GetAverage(x_map);
            double y_Avg = GetAverage(y_map);
            double forecast = 0f;
            double b = 0f;
            double a = 0f;
            double tempTop = 0f;
            double tempBottom = 0f;
            for (int i = 0; i < y_map.Length; i++)
            {
                tempTop += (x_map[i] - x_Avg) * (y_map[i] - y_Avg);
                tempBottom += Math.Pow(((x_map[i] - x_Avg)), 2f);
            }
            b = tempTop / tempBottom;
            a = y_Avg - b * x_Avg;
            forecast = a + b * key;
            return forecast;
        }

        /// <summary>
        /// 得到平均值
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static double GetAverage(double[] data)
        {
            double total = 0;
            for (int i = 0; i < data.Length; i++)
            {
                total += data[i];
            }

            return total / data.Length;
        }
        /// <summary>
        /// 二分查找,查找输入key(x)对应的数组索引
        /// </summary>
        /// <param name="dlist"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        public static int binarySearch(double[] dlist, double x)
        {
            if (x < dlist[0] || x >dlist[dlist.Length - 1]) return -1;

            int low = 0;
            int high = dlist.Length - 1;

            while (low <= high)
            {
                int middle = (low + high) / 2;
                if (middle == dlist.Length - 1)
                {
                    return middle;
                }
                if (dlist[middle] == x)
                {
                    return middle;
                }
                else
                {
                    if (dlist[middle] < x)
                    {

                        if (x < dlist[middle + 1])
                        {
                            return middle;
                        }
                        else
                        {
                            low = middle + 1;
                            continue;
                        }
                    }
                    else
                    {

                        if (x > dlist[middle - 1])
                        {
                            return middle - 1;
                        }
                        else
                        {
                            high = middle - 1;
                            continue;
                        }
                    }
                }
            }
            return -1;
        }

    }

三维插值
通过循环遍历实现
对x1、y1、z1对应key值B、H、Q,依次进行插值,得到最终插值结果。

public static double Insert_3d(double B, double H, double Q)
        {
           
  

            double[,,] arr = new double[3, 4, 4];
            arr = new double[,,] { { { 52.3,53.1,53.9,54.7 },{ 54.9,55.7,56.6,57.4},{ 55.4,56.2,57,57.7},{ 56,56.7,57.5,58.3} },
                                   { { 50.8,51.6,52.4,53.2 },{ 53,53.8,54.6,55.4},{ 53.5,54.2,55,55.8},{ 54,54.7,55.5,56.2} },
                                   { { 49.7,50.6,51.4,52.2 },{ 51.7,52.5,53.4,54.2},{ 52.1,52.9,53.8,54.6},{ 52.6,53.4,54.2,55} } };


            double[] xl = { 4, 6, 8, 10 };
            double[] yl = { 5, 6, 7, 8 };
            double[] zl = { 8, 10, 12 };

            double[] x_values = new double[4];
            double[] y_values = new double[4];
            double[] z_values = new double[3];
            double forecast = 0;
            for (int k = 0; k < 3; k++)
            {

                for (int j = 0; j < 4; j++)
                {

                    for (int i = 0; i < 4; i++)
                    {
                        x_values[i] = arr[k, j, i];

                    }
                    y_values[j] = InterAlgorithm.Compute(xl, x_values, B);
                }
                z_values[k] = InterAlgorithm.Compute(yl, y_values, H);
            }
            forecast = InterAlgorithm.Compute(zl, z_values, Q);

            return forecast;

        }

DeBug过程
在这里插入图片描述

最后

以上就是迷人大树为你收集整理的三维度双线性插值的全部内容,希望文章能够帮你解决三维度双线性插值所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部