C#,数值计算——插值和外推,二维三次样条插值(Spline2D_interp)的计算方法与源程序

news/2025/3/14 23:04:12/

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// 二维三次样条插值
    /// Object for two-dimensional cubic spline interpolation on a matrix.Construct
    /// with a vector of x1 values, a vector of x2 values, and a matrix of tabulated
    /// function values yij.Then call interp for interpolated values.
    /// </summary>
    public class Spline2D_interp
    {
        private int[,] bcucof_wt = new int[,] {
            {  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0 },
            {  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0 },
            { -3,  0,  0,  3,  0,  0,  0,  0, -2,  0,  0, -1,  0,  0,  0,  0 },
            {  2,  0,  0, -2,  0,  0,  0,  0,  1,  0,  0,  1,  0,  0,  0,  0 },
            {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0 },
            {  0,  0,  0,  0, -3,  0,  0,  3,  0,  0,  0,  0, -2,  0,  0, -1 },
            {  0,  0,  0,  0,  2,  0,  0, -2,  0,  0,  0,  0,  1,  0,  0,  1 },
            { -3,  3,  0,  0, -2, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
            {  0,  0,  0,  0,  0,  0,  0,  0, -3,  3,  0,  0, -2, -1,  0,  0 },
            {  9, -9,  9, -9,  6,  3, -3, -6,  6, -6, -3,  3,  4,  2,  1,  2 },
            { -6,  6, -6,  6, -4, -2,  2,  4, -3,  3,  3, -3, -2, -1, -1, -2 },
            {  2, -2,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
            {  0,  0,  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  1,  1,  0,  0 },
            { -6,  6, -6,  6, -3, -3,  3,  3, -4,  4,  2, -2, -2, -2, -1, -1 },
            {  4, -4,  4, -4,  2,  2, -2, -2,  2, -2, -2,  2,  1,  1,  1,  1 }
        };

        private int m { get; set; }
        private int n { get; set; }
        private double[,] y { get; set; }
        private double[] x1 { get; set; }
        private double[] yv { get; set; }
        private Spline_interp[] srp { get; set; }

        public Spline2D_interp(double[] x1v, double[] x2v, double[,] ym)
        {
            this.m = x1v.Length;
            this.n = x2v.Length;
            this.y = ym;
            this.yv = new double[m];
            this.x1 = x1v;
            this.srp = new Spline_interp[m];
            for (int i = 0; i < m; i++)
            {
                srp[i] = new Spline_interp(x2v, y[i, 0]);
            }
        }

        public double interp(double x1p, double x2p)
        {
            for (int i = 0; i < m; i++)
            {
                yv[i] = (srp[i]).interp(x2p);
            }
            Spline_interp scol = new Spline_interp(x1, yv);
            return scol.interp(x1p);
        }

        /// <summary>
        /// Given arrays y[0..3], y1[0..3], y2[0..3], and y12[0..3], containing the
        /// function, gradients, and cross-derivative at the four grid points of a
        /// rectangular grid cell(numbered counterclockwise from the lower left), and
        /// given d1 and d2, the length of the grid cell in the 1 and 2 directions,
        /// this routine returns the table c[0..3][0..3] that is used by routine bcuint
        /// for bicubic interpolation.
        /// </summary>
        /// <param name="y"></param>
        /// <param name="y1"></param>
        /// <param name="y2"></param>
        /// <param name="y12"></param>
        /// <param name="d1"></param>
        /// <param name="d2"></param>
        /// <param name="c"></param>
        private void bcucof(double[] y, double[] y1, double[] y2, double[] y12, double d1, double d2, double[,] c)
        { 
            //int[,] bcucof_wt = new int[16, 16]{ bcucof_wt_d };
            double d1d2 = d1 * d2;
            double[] cl = new double[16];
            double[] x = new double[16];

            for (int i = 0; i < 4; i++)
            {
                x[i] = y[i];
                x[i + 4] = y1[i] * d1;
                x[i + 8] = y2[i] * d2;
                x[i + 12] = y12[i] * d1d2;
            }
            for (int i = 0; i < 16; i++)
            {
                double xx = 0.0;
                for (int k = 0; k < 16; k++)
                {
                    xx += bcucof_wt[i, k] * x[k];
                }
                cl[i] = xx;
            }
            int l = 0;
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    c[i, j] = cl[l++];
                }
            }
        }

        /// <summary>
        /// Bicubic interpolation within a grid square.Input quantities are
        /// y, y1, y2, y12 (as described in bcucof); x1l and x1u, the lower and upper
        /// coordinates of the grid square in the 1 direction; x2l and x2u likewise for
        /// the 2 direction; and x1, x2, the coordinates of the desired point for the
        /// interpolation.The interpolated function value is returned as ansy, and the
        /// interpolated gradient values as ansy1 and ansy2.This routine calls bcucof.
        /// </summary>
        /// <param name="y"></param>
        /// <param name="y1"></param>
        /// <param name="y2"></param>
        /// <param name="y12"></param>
        /// <param name="x1l"></param>
        /// <param name="x1u"></param>
        /// <param name="x2l"></param>
        /// <param name="x2u"></param>
        /// <param name="x1"></param>
        /// <param name="x2"></param>
        /// <param name="ansy"></param>
        /// <param name="ansy1"></param>
        /// <param name="ansy2"></param>
        /// <exception cref="Exception"></exception>
        public void bcuint(double[] y, double[] y1, double[] y2, double[] y12, double x1l, double x1u, double x2l, double x2u, double x1, double x2, ref double ansy, ref double ansy1, ref double ansy2)
        {
            double d1 = x1u - x1l;
            double d2 = x2u - x2l;
            double[,] c = new double[4, 4];
            bcucof(y, y1, y2, y12, d1, d2, c);
            //if (x1u == x1l || x2u == x2l)
            if (Math.Abs(x1u - x1l) <= float.Epsilon || Math.Abs(x2u - x2l) <= float.Epsilon)
            {
                throw new Exception("Bad input in routine bcuint");
            }
            double t = (x1 - x1l) / d1;
            double u = (x2 - x2l) / d2;
            ansy = ansy2 = ansy1 = 0.0;
            for (int i = 3; i >= 0; i--)
            {
                ansy = t * ansy + ((c[i, 3] * u + c[i, 2]) * u + c[i, 1]) * u + c[i, 0];
                ansy2 = t * ansy2 + (3.0 * c[i, 3] * u + 2.0 * c[i, 2]) * u + c[i, 1];
                ansy1 = u * ansy1 + (3.0 * c[3, i] * t + 2.0 * c[2, i]) * t + c[1, i];
            }
            ansy1 /= d1;
            ansy2 /= d2;
        }

    }
}

2 代码格式

using System;namespace Legalsoft.Truffer
{/// <summary>/// 二维三次样条插值/// Object for two-dimensional cubic spline interpolation on a matrix.Construct/// with a vector of x1 values, a vector of x2 values, and a matrix of tabulated/// function values yij.Then call interp for interpolated values./// </summary>public class Spline2D_interp{private int[,] bcucof_wt = new int[,] {{  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0 },{  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0 },{ -3,  0,  0,  3,  0,  0,  0,  0, -2,  0,  0, -1,  0,  0,  0,  0 },{  2,  0,  0, -2,  0,  0,  0,  0,  1,  0,  0,  1,  0,  0,  0,  0 },{  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0 },{  0,  0,  0,  0, -3,  0,  0,  3,  0,  0,  0,  0, -2,  0,  0, -1 },{  0,  0,  0,  0,  2,  0,  0, -2,  0,  0,  0,  0,  1,  0,  0,  1 },{ -3,  3,  0,  0, -2, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },{  0,  0,  0,  0,  0,  0,  0,  0, -3,  3,  0,  0, -2, -1,  0,  0 },{  9, -9,  9, -9,  6,  3, -3, -6,  6, -6, -3,  3,  4,  2,  1,  2 },{ -6,  6, -6,  6, -4, -2,  2,  4, -3,  3,  3, -3, -2, -1, -1, -2 },{  2, -2,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },{  0,  0,  0,  0,  0,  0,  0,  0,  2, -2,  0,  0,  1,  1,  0,  0 },{ -6,  6, -6,  6, -3, -3,  3,  3, -4,  4,  2, -2, -2, -2, -1, -1 },{  4, -4,  4, -4,  2,  2, -2, -2,  2, -2, -2,  2,  1,  1,  1,  1 }};private int m { get; set; }private int n { get; set; }private double[,] y { get; set; }private double[] x1 { get; set; }private double[] yv { get; set; }private Spline_interp[] srp { get; set; }public Spline2D_interp(double[] x1v, double[] x2v, double[,] ym){this.m = x1v.Length;this.n = x2v.Length;this.y = ym;this.yv = new double[m];this.x1 = x1v;this.srp = new Spline_interp[m];for (int i = 0; i < m; i++){srp[i] = new Spline_interp(x2v, y[i, 0]);}}public double interp(double x1p, double x2p){for (int i = 0; i < m; i++){yv[i] = (srp[i]).interp(x2p);}Spline_interp scol = new Spline_interp(x1, yv);return scol.interp(x1p);}/// <summary>/// Given arrays y[0..3], y1[0..3], y2[0..3], and y12[0..3], containing the/// function, gradients, and cross-derivative at the four grid points of a/// rectangular grid cell(numbered counterclockwise from the lower left), and/// given d1 and d2, the length of the grid cell in the 1 and 2 directions,/// this routine returns the table c[0..3][0..3] that is used by routine bcuint/// for bicubic interpolation./// </summary>/// <param name="y"></param>/// <param name="y1"></param>/// <param name="y2"></param>/// <param name="y12"></param>/// <param name="d1"></param>/// <param name="d2"></param>/// <param name="c"></param>private void bcucof(double[] y, double[] y1, double[] y2, double[] y12, double d1, double d2, double[,] c){ //int[,] bcucof_wt = new int[16, 16]{ bcucof_wt_d };double d1d2 = d1 * d2;double[] cl = new double[16];double[] x = new double[16];for (int i = 0; i < 4; i++){x[i] = y[i];x[i + 4] = y1[i] * d1;x[i + 8] = y2[i] * d2;x[i + 12] = y12[i] * d1d2;}for (int i = 0; i < 16; i++){double xx = 0.0;for (int k = 0; k < 16; k++){xx += bcucof_wt[i, k] * x[k];}cl[i] = xx;}int l = 0;for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){c[i, j] = cl[l++];}}}/// <summary>/// Bicubic interpolation within a grid square.Input quantities are/// y, y1, y2, y12 (as described in bcucof); x1l and x1u, the lower and upper/// coordinates of the grid square in the 1 direction; x2l and x2u likewise for/// the 2 direction; and x1, x2, the coordinates of the desired point for the/// interpolation.The interpolated function value is returned as ansy, and the/// interpolated gradient values as ansy1 and ansy2.This routine calls bcucof./// </summary>/// <param name="y"></param>/// <param name="y1"></param>/// <param name="y2"></param>/// <param name="y12"></param>/// <param name="x1l"></param>/// <param name="x1u"></param>/// <param name="x2l"></param>/// <param name="x2u"></param>/// <param name="x1"></param>/// <param name="x2"></param>/// <param name="ansy"></param>/// <param name="ansy1"></param>/// <param name="ansy2"></param>/// <exception cref="Exception"></exception>public void bcuint(double[] y, double[] y1, double[] y2, double[] y12, double x1l, double x1u, double x2l, double x2u, double x1, double x2, ref double ansy, ref double ansy1, ref double ansy2){double d1 = x1u - x1l;double d2 = x2u - x2l;double[,] c = new double[4, 4];bcucof(y, y1, y2, y12, d1, d2, c);//if (x1u == x1l || x2u == x2l)if (Math.Abs(x1u - x1l) <= float.Epsilon || Math.Abs(x2u - x2l) <= float.Epsilon){throw new Exception("Bad input in routine bcuint");}double t = (x1 - x1l) / d1;double u = (x2 - x2l) / d2;ansy = ansy2 = ansy1 = 0.0;for (int i = 3; i >= 0; i--){ansy = t * ansy + ((c[i, 3] * u + c[i, 2]) * u + c[i, 1]) * u + c[i, 0];ansy2 = t * ansy2 + (3.0 * c[i, 3] * u + 2.0 * c[i, 2]) * u + c[i, 1];ansy1 = u * ansy1 + (3.0 * c[3, i] * t + 2.0 * c[2, i]) * t + c[1, i];}ansy1 /= d1;ansy2 /= d2;}}
}


http://www.ppmy.cn/news/1255975.html

相关文章

机器学习 - 导论

简单了解 机器学习关于数据集的概念 、

Python - 字典3

修改字典项 您可以通过引用其键名来更改特定项的值&#xff1a; 示例&#xff0c;将 “year” 更改为 2018&#xff1a; thisdict {"brand": "Ford","model": "Mustang","year": 1964 } thisdict["year"] 20…

基于PHP的在线日语学习平台

有需要请加文章底部Q哦 可远程调试 PHP在线日语学习平台 一 介绍 此日语学习平台基于原生PHP开发&#xff0c;数据库mysql。系统角色分为用户和管理员。(附带参考设计文档) 技术栈&#xff1a;phpmysqlphpstudyvscode 二 功能 学生 1 注册/登录/注销 2 个人中心 3 查看课程…

Java 中如何正确的将 float 转换成 double?

为什么 double 转 float 不会出现数据误差&#xff0c;而 float 转 double 却误差如此之大&#xff1f; double d 3.14; float f (float)d; System.out.println(f);输出结果是:3.14; float f 127.1f; double d f; System.out.println(d);输出结果是&#xff1a;127.09999…

【UGUI】事件侦听EventSystem系统0学

前言介绍 EventSystem是Unity UGUI中的一个重要组件&#xff0c;用于处理用户输入事件&#xff0c;如点击、拖拽、滚动等。它负责将用户输入事件传递给合适的UI元素&#xff0c;并触发相应的事件回调函数&#xff08;就是你想要做的事情&#xff0c;自定义函数&#xff09;。 …

RC低通滤波电路直接带载后会发生什么?

1、滤波的含义 滤波是频域范畴&#xff0c;它说的是不同频率的信号经过一个电路处理后&#xff0c;信号发生变化的问题&#xff0c;变化包含了原始信号幅值和相位的变化&#xff0c;滤波电路对信号的幅值做出的响应称为幅频响应&#xff0c;对信号相位做出的反应称为相频响应。…

【计算机组成原理】存储器知识

目录 1、存储器分类 1.1、按存储介质分类 1.2、按存取方式分类 1.3、按信息的可改写性分类 1.4、按信息的可保存性分类 1.5、按功能和存取速度分类 2、存储器技术指标 2.1、存储容量 2.2、存取速度 3、存储系统层次结构 4、主存的基本结构 5、主存中数据的存放 5.…

Linux DNS服务器相关命令

配置文件&#xff1a; /etc/dnsmasq.conf ### 可以添加修改 address IP 与自定义域名 的对应关系 修改后重启服务&#xff1a;systemctl restart dnsmasq dns服务其他指令&#xff1a; systemctl start dnsmasq systemctl stop dnsmasq systemctl enable dnsmasq ## 开机自启已…