C#,数值计算——数据建模Fitmrq(Levenberg-Marquardt nonlinear fitting)的计算方法与源程序

news2024/11/17 10:46:31

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Levenberg-Marquardt nonlinear fitting
    /// </summary>
    public class Fitmrq
    {
        private const int NDONE = 4;
        private const int ITMAX = 1000;
        private int ndat { get; set; }
        private int ma { get; set; }
        private int mfit { get; set; }
        private double[] x { get; set; }
        private double[] y { get; set; }
        private double[] sig { get; set; }
        private double tol { get; set; }
        private bool[] ia { get; set; }
        private double[] a { get; set; }
        private double[,] covar;
        private double[,] alpha;
        private double chisq { get; set; }
        public MultiFuncd funcs;

        public Fitmrq(double[] xx, double[] yy, double[] ssig, double[] aa, MultiFuncd funks, double TOL = 1.0e-3)
        {
            this.ndat = xx.Length;
            this.ma = aa.Length;
            this.x = xx;
            this.y = yy;
            this.sig = ssig;
            this.tol = TOL;
            this.funcs = funks;
            this.ia = new bool[ma];
            this.alpha = new double[ma, ma];
            this.a = aa;
            this.covar = new double[ma, ma];
            for (int i = 0; i < ma; i++)
            {
                ia[i] = true;
            }
        }

        public void hold(int i, double val)
        {
            ia[i] = false;
            a[i] = val;
        }

        public void free(int i)
        {
            ia[i] = true;
        }

        public void fit()
        {
            int done = 0;
            double alamda = .001;
            double[] atry = new double[ma];
            double[] beta = new double[ma];
            double[] da = new double[ma];
            mfit = 0;
            for (int j = 0; j < ma; j++)
            {
                if (ia[j])
                {
                    mfit++;
                }
            }
            double[,] oneda = new double[mfit, 1];
            double[,] temp = new double[mfit, mfit];
            mrqcof(a, alpha, beta);
            for (int j = 0; j < ma; j++)
            {
                atry[j] = a[j];
            }
            double ochisq = chisq;
            for (int iter = 0; iter < ITMAX; iter++)
            {
                if (done == NDONE)
                {
                    alamda = 0.0;
                }
                for (int j = 0; j < mfit; j++)
                {
                    for (int k = 0; k < mfit; k++)
                    {
                        covar[j, k] = alpha[j, k];
                    }
                    covar[j, j] = alpha[j, j] * (1.0 + alamda);
                    for (int k = 0; k < mfit; k++)
                    {
                        temp[j, k] = covar[j, k];
                    }
                    oneda[j, 0] = beta[j];
                }
                GaussJordan.gaussj( temp,  oneda);
                for (int j = 0; j < mfit; j++)
                {
                    for (int k = 0; k < mfit; k++)
                    {
                        covar[j, k] = temp[j, k];
                    }
                    da[j] = oneda[j, 0];
                }
                if (done == NDONE)
                {
                    covsrt( covar);
                    covsrt( alpha);
                    return;
                }
                for (int j = 0, l = 0; l < ma; l++)
                {
                    if (ia[l])
                    {
                        atry[l] = a[l] + da[j++];
                    }
                }
                mrqcof(atry, covar, da);
                if (Math.Abs(chisq - ochisq) < Math.Max(tol, tol * chisq))
                {
                    done++;
                }
                if (chisq < ochisq)
                {
                    alamda *= 0.1;
                    ochisq = chisq;
                    for (int j = 0; j < mfit; j++)
                    {
                        for (int k = 0; k < mfit; k++)
                        {
                            alpha[j, k] = covar[j, k];
                        }
                        beta[j] = da[j];
                    }
                    for (int l = 0; l < ma; l++)
                    {
                        a[l] = atry[l];
                    }
                }
                else
                {
                    alamda *= 10.0;
                    chisq = ochisq;
                }
            }
            throw new Exception("Fitmrq too many iterations");
        }

        public void mrqcof(double[] a, double[,] alpha, double[] beta)
        {
            double ymod = 0.0;
            double[] dyda = new double[ma];
            for (int j = 0; j < mfit; j++)
            {
                for (int k = 0; k <= j; k++)
                {
                    alpha[j, k] = 0.0;
                }
                beta[j] = 0.0;
            }
            chisq = 0.0;
            for (int i = 0; i < ndat; i++)
            {
                funcs.funk(x[i], a, ref ymod,  dyda);
                double sig2i = 1.0 / (sig[i] * sig[i]);
                double dy = y[i] - ymod;
                for (int j = 0, l = 0; l < ma; l++)
                {
                    if (ia[l])
                    {
                        double wt = dyda[l] * sig2i;
                        for (int k = 0, m = 0; m < l + 1; m++)
                        {
                            if (ia[m])
                            {
                                alpha[j, k++] += wt * dyda[m];
                            }
                        }
                        beta[j++] += dy * wt;
                    }
                }
                chisq += dy * dy * sig2i;
            }
            for (int j = 1; j < mfit; j++)
            {
                for (int k = 0; k < j; k++)
                {
                    alpha[k, j] = alpha[j, k];
                }
            }
        }

        public void covsrt(double[,] covar)
        {
            for (int i = mfit; i < ma; i++)
            {
                for (int j = 0; j < i + 1; j++)
                {
                    covar[i, j] = covar[j, i] = 0.0;
                }
            }
            int k = mfit - 1;
            for (int j = ma - 1; j >= 0; j--)
            {
                if (ia[j])
                {
                    for (int i = 0; i < ma; i++)
                    {
                        Globals.SWAP(ref covar[i, k], ref covar[i, j]);
                    }
                    for (int i = 0; i < ma; i++)
                    {
                        Globals.SWAP(ref covar[k, i], ref covar[j, i]);
                    }
                    k--;
                }
            }
        }
    }
}
 

2 代码格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Levenberg-Marquardt nonlinear fitting
    /// </summary>
    public class Fitmrq
    {
        private const int NDONE = 4;
        private const int ITMAX = 1000;
        private int ndat { get; set; }
        private int ma { get; set; }
        private int mfit { get; set; }
        private double[] x { get; set; }
        private double[] y { get; set; }
        private double[] sig { get; set; }
        private double tol { get; set; }
        private bool[] ia { get; set; }
        private double[] a { get; set; }
        private double[,] covar;
        private double[,] alpha;
        private double chisq { get; set; }
        public MultiFuncd funcs;

        public Fitmrq(double[] xx, double[] yy, double[] ssig, double[] aa, MultiFuncd funks, double TOL = 1.0e-3)
        {
            this.ndat = xx.Length;
            this.ma = aa.Length;
            this.x = xx;
            this.y = yy;
            this.sig = ssig;
            this.tol = TOL;
            this.funcs = funks;
            this.ia = new bool[ma];
            this.alpha = new double[ma, ma];
            this.a = aa;
            this.covar = new double[ma, ma];
            for (int i = 0; i < ma; i++)
            {
                ia[i] = true;
            }
        }

        public void hold(int i, double val)
        {
            ia[i] = false;
            a[i] = val;
        }

        public void free(int i)
        {
            ia[i] = true;
        }

        public void fit()
        {
            int done = 0;
            double alamda = .001;
            double[] atry = new double[ma];
            double[] beta = new double[ma];
            double[] da = new double[ma];
            mfit = 0;
            for (int j = 0; j < ma; j++)
            {
                if (ia[j])
                {
                    mfit++;
                }
            }
            double[,] oneda = new double[mfit, 1];
            double[,] temp = new double[mfit, mfit];
            mrqcof(a, alpha, beta);
            for (int j = 0; j < ma; j++)
            {
                atry[j] = a[j];
            }
            double ochisq = chisq;
            for (int iter = 0; iter < ITMAX; iter++)
            {
                if (done == NDONE)
                {
                    alamda = 0.0;
                }
                for (int j = 0; j < mfit; j++)
                {
                    for (int k = 0; k < mfit; k++)
                    {
                        covar[j, k] = alpha[j, k];
                    }
                    covar[j, j] = alpha[j, j] * (1.0 + alamda);
                    for (int k = 0; k < mfit; k++)
                    {
                        temp[j, k] = covar[j, k];
                    }
                    oneda[j, 0] = beta[j];
                }
                GaussJordan.gaussj( temp,  oneda);
                for (int j = 0; j < mfit; j++)
                {
                    for (int k = 0; k < mfit; k++)
                    {
                        covar[j, k] = temp[j, k];
                    }
                    da[j] = oneda[j, 0];
                }
                if (done == NDONE)
                {
                    covsrt( covar);
                    covsrt( alpha);
                    return;
                }
                for (int j = 0, l = 0; l < ma; l++)
                {
                    if (ia[l])
                    {
                        atry[l] = a[l] + da[j++];
                    }
                }
                mrqcof(atry, covar, da);
                if (Math.Abs(chisq - ochisq) < Math.Max(tol, tol * chisq))
                {
                    done++;
                }
                if (chisq < ochisq)
                {
                    alamda *= 0.1;
                    ochisq = chisq;
                    for (int j = 0; j < mfit; j++)
                    {
                        for (int k = 0; k < mfit; k++)
                        {
                            alpha[j, k] = covar[j, k];
                        }
                        beta[j] = da[j];
                    }
                    for (int l = 0; l < ma; l++)
                    {
                        a[l] = atry[l];
                    }
                }
                else
                {
                    alamda *= 10.0;
                    chisq = ochisq;
                }
            }
            throw new Exception("Fitmrq too many iterations");
        }

        public void mrqcof(double[] a, double[,] alpha, double[] beta)
        {
            double ymod = 0.0;
            double[] dyda = new double[ma];
            for (int j = 0; j < mfit; j++)
            {
                for (int k = 0; k <= j; k++)
                {
                    alpha[j, k] = 0.0;
                }
                beta[j] = 0.0;
            }
            chisq = 0.0;
            for (int i = 0; i < ndat; i++)
            {
                funcs.funk(x[i], a, ref ymod,  dyda);
                double sig2i = 1.0 / (sig[i] * sig[i]);
                double dy = y[i] - ymod;
                for (int j = 0, l = 0; l < ma; l++)
                {
                    if (ia[l])
                    {
                        double wt = dyda[l] * sig2i;
                        for (int k = 0, m = 0; m < l + 1; m++)
                        {
                            if (ia[m])
                            {
                                alpha[j, k++] += wt * dyda[m];
                            }
                        }
                        beta[j++] += dy * wt;
                    }
                }
                chisq += dy * dy * sig2i;
            }
            for (int j = 1; j < mfit; j++)
            {
                for (int k = 0; k < j; k++)
                {
                    alpha[k, j] = alpha[j, k];
                }
            }
        }

        public void covsrt(double[,] covar)
        {
            for (int i = mfit; i < ma; i++)
            {
                for (int j = 0; j < i + 1; j++)
                {
                    covar[i, j] = covar[j, i] = 0.0;
                }
            }
            int k = mfit - 1;
            for (int j = ma - 1; j >= 0; j--)
            {
                if (ia[j])
                {
                    for (int i = 0; i < ma; i++)
                    {
                        Globals.SWAP(ref covar[i, k], ref covar[i, j]);
                    }
                    for (int i = 0; i < ma; i++)
                    {
                        Globals.SWAP(ref covar[k, i], ref covar[j, i]);
                    }
                    k--;
                }
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1083167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【【萌新的SOC学习之GPIO之MIO控制LED实验程序设计】】

萌新的SOC学习之GPIO之MIO控制LED实验程序设计 如何设置完GPIO并且传递数据 我们先了解GPIO引脚的配置 每一个GPIO引脚都可以设置成输入输出 &#xff0c;只有GPIO8 7 只能作为输出 我们现在做一个例子 GPIO 的bank我们知道有4个 bank0 1 2 3 DIRM_0 就是第一个bank 需要写入…

tecplot的使曲线光滑的方法

在对流场模拟结果进行处理时&#xff0c;不可避免的存在些许的噪声导致tecplot的曲线不光滑&#xff0c;故介绍一下tecplot中曲线光滑的方法 1.选择data-alter 2.data中选择smooth,通过调节number of passes&#xff0c;调节曲线光滑程度 大功告成&#xff01; 最近发现写的文…

防反接方案,NMOS PMOS

NMOS电路的缺陷 1.1&#xff0c;由于NMOS具有内阻&#xff0c;我们可以把它设为Rdson, 那么电优先会从低电阻串口处走&#xff0c;这样会有烧毁串口地的风险。 1.2&#xff0c;短期内的方案是&#xff0c;可以在串口处串接1个100ohm电阻。 PMOS电路

基于Springboot实现口腔牙诊所管理平台项目【项目源码+论文说明】

基于Springboot实现口腔牙科诊所管理平台演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;口腔管理平台当然也不能排除在外。口腔管理平台是以实际运用为开发背景&am…

oracle connect by详解

1、作用&#xff1a; 用于存在父子&#xff0c;祖孙&#xff0c;上下级等层级关系的数据表进行层级查询。 2、语法 SELECT ... FROM .... START WITH cond1 CONNECT BY cond2 WHERE cond3;2.1、说明 start with: 指定起始节点的条件 connect by: 指定父子行的条件关系 …

geecg-uniapp 路由修改 页面创建 (2)

首先打开 首页面 &#xff08;1&#xff09;我们以home的常用服务 为例 我们修改 usList 数据 &#xff08;2&#xff09;查找对应路径 work.js 我们修改荒石对应的路径 现在跳转 helloword &#xff08;3&#xff09;修改跳转路径 &#xff08;4&#xff09;创建页面 …

Python —— 接口测试之使用requests发起请求实战

1、认识requests模块 1、requests介绍 requests是一个第三方库&#xff0c;因此首先需要安装这个库&#xff0c;安装三步走&#xff1a; 安装&#xff1a;pip install requests在文件中引用这个模块&#xff1a;import requests使用这个库发起一个请求&#xff08;get请求、…

C++——容器适配器

1. 什么是适配器&#xff1f; 容器适配器是C标准库中的一种数据结构&#xff0c;它可以将不同类型的容器&#xff08;如vector、list、deque等&#xff09;转换为另一种类型的容器。容器适配器提供了一种简单的方式来重新组织和访问数据&#xff0c;同时隐藏了底层容器的实现细…

C++ 多维数组

C 支持多维数组。多维数组声明的一般形式如下&#xff1a; type name[size1][size2]...[sizeN];例如&#xff0c;下面的声明创建了一个三维 5 . 10 . 4 整型数组&#xff1a; int threedim[5][10][4];二维数组 多维数组最简单的形式是二维数组。一个二维数组&#xff0c;在本…

vue启用打印机打印-二维码条形码打印

起因 资产、设备管理必备的二维码条形码打印 原理 所需插件 vue-print-nb 本文版本1.7.5 构建所需要打印的内容&#xff0c;利用vue-print-nb进行打印。二维码条形码打印的本质就是图片打印 代码 html部分 <div ref"printDom"id"printDom">//…

Linux内存管理 | 二、虚拟地址空间布局

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强企业&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

SNAP计算哨兵2号的LAI/FVC/FAPAR

SNAP计算LAI 简介 SNAP的计算LAI方法是基于PROSAIL模型&#xff0c;集成的模块&#xff0c;很方便。 首先要下载SNAP软件&#xff0c;下载步骤见博文 打开数据 找到影像的.xml文件 拖入左边的空白框中&#xff0c;发现所有波段会显示如下。这些数据都是已经经过处理完成之后…

Vue之VueX知识探索(一起了解关于VueX的新世界)

目录 前言 一、VueX简介 1. 什么是VueX 2. VueX的作用及重要性 3. VueX的应用场景 二、VueX的使用准备工作 1. 下载安装VueX 2. vuex获取值以及改变值 2.1 创建所需示例 2.2 将创建好的.vue文件页面显示 2.3 创建VueX的相关文件 2.4 配置VueX四个js文件 2.5 加载到vue示…

网络架构介绍

1 网络 7 层架构 7 层模型主要包括&#xff1a; 1. 物理层&#xff1a;主要定义物理设备标准&#xff0c;如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流&#xff08;就是由 1、0 转化为电流强弱来进行传输,到达目的地后在转化为1、0…

简述电子设计中的EMC、EMI、ESD

简述电子设计中的EMC、EMI、ESD ESD EMI EMC ESD、EMI、EMC 设计是电子工程师在设计中遇到最常见的难题&#xff0c;电磁兼容性&#xff08;EMC&#xff09;是指设备或系统在其电磁环境中符合要求运行并不对其环境中的任何设备产生无法忍受的电磁干扰的能力。 因此&#xff0…

【2023年11月第四版教材】第24章《法律法规与标准规范》(合集篇)

第24章《法律法规与标准规范》(合集篇&#xff09; 1 民法典&#xff08;合同编&#xff09;2 招标投标法2.1 关于时间的总结2.2 内容 3 政府采购法4 专利法5 著作权法6 商标法7 网络安全法8 数据安全法 1 民法典&#xff08;合同编&#xff09; 1、要约是希望和他人订立合同的…

LLM - 旋转位置编码 RoPE 代码详解

目录 一.引言 二.RoPE 理论 1.RoPE 矩阵形式 2.RoPE 图例形式 3.RoPE 实践分析 三.RoPE 代码分析 1.源码获取 2.源码分析 3.rotary_emb 3.1 __init__ 3.2 forward 4.apply_rotary_pos_emb 4.1 rotate_half 4.2 apply_rotary_pos_emb 四.RoPE 代码实现 1.Q/K/V …

苹果ios开发者ipa文件包内测人数签名真机数量满了应该怎么做?

苹果ios开发者ipa文件包内测人数签名真机数量满了应该怎么做&#xff1f; 有人总是问我开发者的设备满了怎么做才可以让设备增加&#xff1f;或者我要怎么做才能让员工的设备都可以安装&#xff0c;那么首先我们要做到的就是要知道我们的开发者都是拥有多少内测设备&#xff1f…

放大器的输入、输出电压范围的理解

问题电路 由于运放SGM8295不是轨到轨的电路&#xff0c;导致U29.1输出电压只有当输入到一定门限的时候才会有输出。 上图表示输入电压工作范围为如上&#xff0c;在此以外的不能正常工作。 一篇很好的运放的输入/输出文章介绍 https://zhuanlan.zhihu.com/p/351740051?utm_id0…

【Java学习之道】异常的处理方式

引言 今天我们将聚焦于异常处理&#xff0c;这是每一个Java程序员都应该掌握的核心技能之一。通过学习这些内容&#xff0c;你将能够更好地应对程序中的意外情况&#xff0c;提高程序的健壮性和可靠性。 一、异常的处理方式 在Java中&#xff0c;异常处理主要通过使用try-ca…