C#,数值计算——计算实对称矩阵所有特征值和特征向量的雅可比(Jacobi)方法与源程序

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Computes all eigenvalues and eigenvectors of
    /// a real symmetric matrix by Jacobi's method.
    /// </summary>
    public class Jacobi
    {
        private int n { get; set; }
        private double[,] a;
        private double[,] v;
        private double[] d;
        private int nrot { get; set; }
        private double EPS { get; set; }


        /// <summary>
        /// Computes all eigenvalues and eigenvectors of a real symmetric matrix
        /// a[0..n - 1][0..n - 1]. On output, d[0..n - 1] contains the eigenvalues of a
        /// sorted into descending order, while v[0..n - 1][0..n - 1] is a matrix whose
        /// columns contain the corresponding normalized eigenvectors.nrot contains
        /// the number of Jacobi rotations that were required.Only the upper triangle
        /// of a is accessed.
        /// </summary>
        /// <param name="aa"></param>
        /// <exception cref="Exception"></exception>
        public Jacobi(double[,] aa)
        {
            this.n = aa.GetLength(0);
            this.a = aa;
            this.v = new double[n, n];
            this.d = new double[n];
            this.nrot = 0;
            this.EPS = float.Epsilon;

            double[] b = new double[n];
            double[] z = new double[n];

            for (int ip = 0; ip < n; ip++)
            {
                for (int iq = 0; iq < n; iq++)
                {
                    v[ip, iq] = 0.0;
                }
                v[ip, ip] = 1.0;
            }
            for (int ip = 0; ip < n; ip++)
            {
                b[ip] = d[ip] = a[ip, ip];
                z[ip] = 0.0;
            }
            for (int i = 1; i <= 50; i++)
            {
                double sm = 0.0;
                for (int ip = 0; ip < n - 1; ip++)
                {
                    for (int iq = ip + 1; iq < n; iq++)
                    {
                        sm += Math.Abs(a[ip, iq]);
                    }
                }
                //if (sm == 0.0)
                if (Math.Abs(sm) <= float.Epsilon)
                {
                    eigsrt( d,  v);
                    return;
                }
                double tresh;
                if (i < 4)
                {
                    tresh = 0.2 * sm / (n * n);
                }
                else
                {
                    tresh = 0.0;
                }
                for (int ip = 0; ip < n - 1; ip++)
                {
                    for (int iq = ip + 1; iq < n; iq++)
                    {
                        double g = 100.0 * Math.Abs(a[ip, iq]);
                        if (i > 4 && g <= EPS * Math.Abs(d[ip]) && g <= EPS * Math.Abs(d[iq]))
                        {
                            a[ip, iq] = 0.0;
                        }
                        else if (Math.Abs(a[ip, iq]) > tresh)
                        {
                            double h = d[iq] - d[ip];
                            double t;
                            if (g <= EPS * Math.Abs(h))
                            {
                                t = (a[ip, iq]) / h;
                            }
                            else
                            {
                                double theta = 0.5 * h / (a[ip, iq]);
                                t = 1.0 / (Math.Abs(theta) + Math.Sqrt(1.0 + theta * theta));
                                if (theta < 0.0)
                                {
                                    t = -t;
                                }
                            }
                            double c = 1.0 / Math.Sqrt(1 + t * t);
                            double s = t * c;
                            double tau = s / (1.0 + c);
                            h = t * a[ip, iq];
                            z[ip] -= h;
                            z[iq] += h;
                            d[ip] -= h;
                            d[iq] += h;
                            a[ip, iq] = 0.0;
                            for (int j = 0; j < ip; j++)
                            {
                                rot( a, s, tau, j, ip, j, iq);
                            }
                            for (int j = ip + 1; j < iq; j++)
                            {
                                rot( a, s, tau, ip, j, j, iq);
                            }
                            for (int j = iq + 1; j < n; j++)
                            {
                                rot( a, s, tau, ip, j, iq, j);
                            }
                            for (int j = 0; j < n; j++)
                            {
                                rot( v, s, tau, j, ip, j, iq);
                            }
                            ++nrot;
                        }
                    }
                }
                for (int ip = 0; ip < n; ip++)
                {
                    b[ip] += z[ip];
                    d[ip] = b[ip];
                    z[ip] = 0.0;
                }
            }
            throw new Exception("Too many iterations in routine jacobi");
        }

        public void rot(double[,] a, double s, double tau, int i, int j, int k, int l)
        {
            double g = a[i, j];
            double h = a[k, l];
            a[i, j] = g - s * (h + g * tau);
            a[k, l] = h + s * (g - h * tau);
        }

        /// <summary>
        /// Given the eigenvalues d[0..n - 1] and(optionally) the eigenvectors
        /// v[0..n - 1][0..n - 1] as determined by Jacobi or tqli, this routine sorts the
        /// eigenvalues into descending order and rearranges the columns of v
        /// correspondingly.The method is straight insertion.
        /// </summary>
        /// <param name="d"></param>
        /// <param name="v"></param>
        public static void eigsrt(double[] d, double[,] v)
        {
            int k;
            int n = d.Length;
            for (int i = 0; i < n - 1; i++)
            {
                double p = d[k = i];
                for (int j = i; j < n; j++)
                {
                    if (d[j] >= p)
                    {
                        p = d[k = j];
                    }
                }
                if (k != i)
                {
                    d[k] = d[i];
                    d[i] = p;
                    if (v != null)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            p = v[j, i];
                            v[j, i] = v[j, k];
                            v[j, k] = p;
                        }
                    }
                }
            }
        }
    }
}
 

2 代码格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Computes all eigenvalues and eigenvectors of
    /// a real symmetric matrix by Jacobi's method.
    /// </summary>
    public class Jacobi
    {
        private int n { get; set; }
        private double[,] a;
        private double[,] v;
        private double[] d;
        private int nrot { get; set; }
        private double EPS { get; set; }


        /// <summary>
        /// Computes all eigenvalues and eigenvectors of a real symmetric matrix
        /// a[0..n - 1][0..n - 1]. On output, d[0..n - 1] contains the eigenvalues of a
        /// sorted into descending order, while v[0..n - 1][0..n - 1] is a matrix whose
        /// columns contain the corresponding normalized eigenvectors.nrot contains
        /// the number of Jacobi rotations that were required.Only the upper triangle
        /// of a is accessed.
        /// </summary>
        /// <param name="aa"></param>
        /// <exception cref="Exception"></exception>
        public Jacobi(double[,] aa)
        {
            this.n = aa.GetLength(0);
            this.a = aa;
            this.v = new double[n, n];
            this.d = new double[n];
            this.nrot = 0;
            this.EPS = float.Epsilon;

            double[] b = new double[n];
            double[] z = new double[n];

            for (int ip = 0; ip < n; ip++)
            {
                for (int iq = 0; iq < n; iq++)
                {
                    v[ip, iq] = 0.0;
                }
                v[ip, ip] = 1.0;
            }
            for (int ip = 0; ip < n; ip++)
            {
                b[ip] = d[ip] = a[ip, ip];
                z[ip] = 0.0;
            }
            for (int i = 1; i <= 50; i++)
            {
                double sm = 0.0;
                for (int ip = 0; ip < n - 1; ip++)
                {
                    for (int iq = ip + 1; iq < n; iq++)
                    {
                        sm += Math.Abs(a[ip, iq]);
                    }
                }
                //if (sm == 0.0)
                if (Math.Abs(sm) <= float.Epsilon)
                {
                    eigsrt( d,  v);
                    return;
                }
                double tresh;
                if (i < 4)
                {
                    tresh = 0.2 * sm / (n * n);
                }
                else
                {
                    tresh = 0.0;
                }
                for (int ip = 0; ip < n - 1; ip++)
                {
                    for (int iq = ip + 1; iq < n; iq++)
                    {
                        double g = 100.0 * Math.Abs(a[ip, iq]);
                        if (i > 4 && g <= EPS * Math.Abs(d[ip]) && g <= EPS * Math.Abs(d[iq]))
                        {
                            a[ip, iq] = 0.0;
                        }
                        else if (Math.Abs(a[ip, iq]) > tresh)
                        {
                            double h = d[iq] - d[ip];
                            double t;
                            if (g <= EPS * Math.Abs(h))
                            {
                                t = (a[ip, iq]) / h;
                            }
                            else
                            {
                                double theta = 0.5 * h / (a[ip, iq]);
                                t = 1.0 / (Math.Abs(theta) + Math.Sqrt(1.0 + theta * theta));
                                if (theta < 0.0)
                                {
                                    t = -t;
                                }
                            }
                            double c = 1.0 / Math.Sqrt(1 + t * t);
                            double s = t * c;
                            double tau = s / (1.0 + c);
                            h = t * a[ip, iq];
                            z[ip] -= h;
                            z[iq] += h;
                            d[ip] -= h;
                            d[iq] += h;
                            a[ip, iq] = 0.0;
                            for (int j = 0; j < ip; j++)
                            {
                                rot( a, s, tau, j, ip, j, iq);
                            }
                            for (int j = ip + 1; j < iq; j++)
                            {
                                rot( a, s, tau, ip, j, j, iq);
                            }
                            for (int j = iq + 1; j < n; j++)
                            {
                                rot( a, s, tau, ip, j, iq, j);
                            }
                            for (int j = 0; j < n; j++)
                            {
                                rot( v, s, tau, j, ip, j, iq);
                            }
                            ++nrot;
                        }
                    }
                }
                for (int ip = 0; ip < n; ip++)
                {
                    b[ip] += z[ip];
                    d[ip] = b[ip];
                    z[ip] = 0.0;
                }
            }
            throw new Exception("Too many iterations in routine jacobi");
        }

        public void rot(double[,] a, double s, double tau, int i, int j, int k, int l)
        {
            double g = a[i, j];
            double h = a[k, l];
            a[i, j] = g - s * (h + g * tau);
            a[k, l] = h + s * (g - h * tau);
        }

        /// <summary>
        /// Given the eigenvalues d[0..n - 1] and(optionally) the eigenvectors
        /// v[0..n - 1][0..n - 1] as determined by Jacobi or tqli, this routine sorts the
        /// eigenvalues into descending order and rearranges the columns of v
        /// correspondingly.The method is straight insertion.
        /// </summary>
        /// <param name="d"></param>
        /// <param name="v"></param>
        public static void eigsrt(double[] d, double[,] v)
        {
            int k;
            int n = d.Length;
            for (int i = 0; i < n - 1; i++)
            {
                double p = d[k = i];
                for (int j = i; j < n; j++)
                {
                    if (d[j] >= p)
                    {
                        p = d[k = j];
                    }
                }
                if (k != i)
                {
                    d[k] = d[i];
                    d[i] = p;
                    if (v != null)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            p = v[j, i];
                            v[j, i] = v[j, k];
                            v[j, k] = p;
                        }
                    }
                }
            }
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CUDA简介——Grid和Block内Thread索引

1. 引言 前序博客&#xff1a; CUDA简介——基本概念CUDA简介——编程模式CUDA简介——For循环并行化 Thread Index&#xff1a; 每个Thread都有其thread index。 在Kernel中&#xff0c;可通过内置的threadIdx变量来获取其thread index。threadIdx为三维的&#xff0c;有相…

音频录制软件哪个好?帮助你找到最合适的一款

音频录制软件是日常工作、学习和创作中不可或缺的一部分。选择一个适合自己需求的录音软件对于确保音频质量和提高工作效率至关重要。可是您知道音频录制软件哪个好吗&#xff1f;本文将深入探讨两种常见的音频录制软件&#xff0c;通过详细的步骤指南&#xff0c;帮助您了解它…

记一次引入低版本包导致包冲突,表现为NoClassDefFoundError的故障

简而言之&#xff0c;因为参考别的项目处理excel的代码if(org.apache.poi.hssf.usermodel.HSSFDateUtil.isCellDateFormatted(cell)) &#xff0c;为了使用这个HSSFDateUtil类我引入了依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><a…

Python3 GUI 自制音乐播放器 图片浏览 图片轮播 PyQt5(附下载地址)

目录 Part1&#xff1a; 介绍 Part2: create window Part2: create window Adv Part4: Music Play Part5&#xff1a; 图片加载&#xff1a; Part1&#xff1a; 介绍 在这篇文章中&#xff0c;我们将学习如何使用PyQt 库创建一个基本的窗口应用程序&#xff0c;并进行一些…

【C/PTA —— 14.结构体1(课内实践)】

C/PTA —— 14.结构体1&#xff08;课内实践&#xff09; 6-1 计算两个复数之积6-2 结构体数组中查找指定编号人员6-3 综合成绩6-4 结构体数组按总分排序 6-1 计算两个复数之积 struct complex multiply(struct complex x, struct complex y) {struct complex product;product.…

1-4、调试汇编程序

语雀原文链接 文章目录 1、执行过程第一步&#xff1a;源程序第二步&#xff1a;编译连接第三步&#xff1a;执行 2、DOSBox运行程序第1步 进入EDIT.EXE第2步 编写源程序第3步 编译第4步 连接第5步 执行完整过程 3、DEBUG跟踪执行过程加载程序到内存执行程序debug和源程序数字…

Selenium 自动化高级操作与解决疑难杂症,如无法连接、使用代理等

解决 Selenium 自动化中的常见疑难杂症 这里记录一些关于 Selenium的常用操作和疑难杂症。 有一些细节的知识点就不重复介绍了&#xff0c;因为之前的文章中都有&#xff01; 如果对本文中的知识点有疑问的&#xff0c;可以先阅读我以前分享的文章&#xff01; 知识点&…

【滑动窗口】LeetCode2953:统计完全子字符串

作者推荐 [二分查找]LeetCode2040:两个有序数组的第 K 小乘积 本题其它解法 【离散差分】LeetCode2953:统计完全子字符串 题目 给你一个字符串 word 和一个整数 k 。 如果 word 的一个子字符串 s 满足以下条件&#xff0c;我们称它是 完全字符串&#xff1a; s 中每个字符…

【UGUI】sprite精灵的创建与编辑

如何切图&#xff08;sprite editor&#xff09; 有时候一张图可能包含了很多张子图&#xff0c;就需要在Unity 临时处理一下&#xff0c;切开&#xff0c;比如动画序列帧图集 虽然我们可以在PS里面逐个切成一样的尺寸导出多张&#xff0c;再放回Unity&#xff0c;但是不需要这…

通讯录管理系统(基于C语言)

模块设计 本通讯录管理系统功能模块共包括9个部分&#xff1a;1.输入数据、2.显示数据、 3.插入数据、4.删除数据、5.查看数据、6.修改数据、7.保存数据、 8.返回主菜单、9.退出系统. 一&#xff0e;总体设计 通讯录的每一条信息包括&#xff1a;姓名、性别、住址、联系电话…

[leetcode ~二叉树] 模版

文章目录 1. 左叶子之和2. 翻转二叉树 E 1. 左叶子之和 :::details 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&…

java生成邮件eml文件例子

提前导入javamail.jar 仓库地址 仓库服务 导入引用类方法 import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.io.FileOutputStream; import java.util.Properties…

10、外观模式(Facade Pattern,不常用)

外观模式&#xff08;Facade Pattern&#xff09;也叫作门面模式&#xff0c;通过一个门面&#xff08;Facade&#xff09;向客户端提供一个访问系统的统一接口&#xff0c;客户端无须关心和知晓系统内部各子模块&#xff08;系统&#xff09;之间的复杂关系&#xff0c;其主要…

利用DateFormat、Date、Calendar等相关类,编程实现如下功能

&#xff08;1&#xff09;用户输入2个日期&#xff0c;第一个日期用整数形式输入&#xff0c;把输入的整数设置为日历对象1的年月日的值。第二个日期以字符串形式输入&#xff0c;形如“2022-10-25”&#xff0c;并设置为日历对象2的年月日的值。将2个日期以“xx年xx月xx日”的…

国际语音呼叫中心适用的行业有哪些?

国际语音呼叫中心的出现&#xff0c;使企业可以在全球范围内提供统一的客户支持&#xff0c;有效地解决客户服务、市场营销等国际性电话沟通问题&#xff0c;为企业提供了卓越的全球客户服务&#xff0c;确保客户在不同国家和地区之间获得一致的、高质量的支持。那么哪些行业适…

熬夜会秃头——beta冲刺Day5

这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day5团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 一、团队成员会议总结 1、成员工作…

代码随想录刷题题Day5

刷题的第五天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C / Python Day5 任务 ● 哈希表理论基础 ● 242.有效的字母异位词 ● 349. 两个数组的交集 ● 202. 快乐数 ● 1. 两数之和 1 哈希表理…

Db2的Activity event monitor在Db2 MPP V2上收集ROWS_INSERTED信息

注&#xff1a;本文不是讲解Db2 Activity event monitor&#xff0c;只是一个用法实践。要了解Activity event monitor&#xff0c;请参考 https://www.ibm.com/docs/en/db2/11.5?topicevents-activity-event-monitoring 。 环境 Red Hat Enterprise Linux release 8.8 (Oot…

“构建智慧城市,共享美好生活“2024杭州国际智慧城市展览会

智慧城市作为当今社会发展的必然趋势&#xff0c;正在被越来越多的企业和观众所关注。为了进一步推动智慧城市的发展&#xff0c;2024杭州智慧城市展览会将于4月份在杭州国际博览中心盛大召开。目前&#xff0c;招商工作已近半程&#xff0c;大批国内外知名企业踊跃报名&#x…

会话技术(Cookie与Session)

会话技术 一.作用域对象 1.作用域对象概述 有作用域的对象作用域对象可以用来存储数据并且可以在不同的组件之间进行传递传递的范围受作用域的限制&#xff0c;一旦超过范围&#xff0c;立即失效 2.两个作用域对象 作用域对象描述request对象作用范围是一次请求ServletCon…