三对角矩阵原理及C++实现

news2024/11/23 12:37:38

一、三对角矩阵

1.三对角矩阵概念

在这里插入图片描述

2.三对角矩阵元素数量

对于给定n阶方阵M,若其为三对角矩阵,则元素个数N为:

  • n=1,此时方阵只有一个元素M[0][0],由定义知该元素也在三对角线上。故N=1
  • n>1,由三对角矩阵特点知,矩阵的第一行和最后一行(第n行)分别有两个非零元素,其余行每行各有三个非零元素。故N = 3*(n-2)+2*2 = 3n-2

综上,
N = { 1 , n=1 3 n − 2 , n>1 N=\left\{ \begin{aligned} & 1 ,&\text{n=1}\\ & 3n-2, &\text{n>1}\\ \end{aligned} \right. N={1,3n2,n=1n>1

3.三对角矩阵下标变换推导(行优先和列优先)

对于给定n阶三对角方阵M和存放该方阵的数组A,非零元素M_ij1≤i,j≤n|i-j|≤1)同数组元素A[k]0≤k<N)存在一一对应的关系。下面分别推导从下标i,jkki,j的关系。

3.1行优先

  1. M_ijA[k]:即已知i,j要找出对应的k,需要知道,在数组A中,元素M_ij之前存放的元素个数num,则M_ij存放在A的第num+1个位置,对应数组A的下标正好为num(假设数组下标从0开始)。
  • 先考虑i>1的情况,即寻找第一行以下的非零元素M_ij
    • 第一行有2个非零元素;之后的2~i-1行,每行有三个非零元素。

    • i行,在M_ij之前的非零元素有j-(i-1)个。

k = num = 2+3*(i-1-1)+j-(i-1)=2i+j-3

  • 而当i=1时,有j=1或2。且A[0]=M_11,A[1]=M_12。代入发现也符合上述公式。
    在这里插入图片描述
  1. A[k]M_ij

首先求出A[k]位于M的第几行:由于M的第一行有两个元素,2~i-1行有三个元素,由此可以得到i关于k的表达式:i = ⌊(k+1)/3+1⌋(下取整)。(i+1为第一行“补”一个元素,加一是因为i从1开始)。
然后可以根据上面得到的ki,j的关系得到:j = k-2i+3

3.列优先

由于三对角矩阵具有良好的对称性,所以只需要对行优先推导得到的关系中i,j互换即可。
即:

  • k=2j+i-3
  • j=⌊(k+1)/3+1⌋(下取整)i=k-2j+3

二、C++实现三对角矩阵代码

//diagonalMatrix.hpp
#pragma once
#include "assert.h"
#include <iostream>
template <typename E>
// 检查下标越界
#define CHECK(i, j) \
    assert(i >= 1 && j >= 1 && i <= m_dimension && j <= m_dimension);

// 检查是否是对角阵中的非零元素
#define IS_ZERO(i, j) abs(i - j) > 1

// 根据行/列优先原则获取数组对应下标
#define GET_IDX(i, j) m_priority ? (2 * i + j - 3) : (2 * j + i - 3)

class DiagonalMatrix
{
private:
    int m_dimension; // 方阵阶数
    int m_capacity;  // 数组容量,即方阵中非零元素数量
    E *m_array;      // 存储方阵的数组
    bool m_priority; // 0: 行优先 1:列优先
public:
    DiagonalMatrix(int dimension, bool priority = false) : m_dimension(dimension), m_priority(priority)
    {
        assert(dimension >= 1);
        if (dimension == 1)

            m_capacity = 1;

        else
            m_capacity = 3 * dimension - 2; // capacity = (d - 2)*3 + 2*2 = 3d -2
        m_array = new E[m_capacity];
    }
    ~DiagonalMatrix()
    {
        delete m_array;
        m_array = nullptr;
    }
    // 设置元素M_ij
    void set(const E &element, int i, int j)
    {
        CHECK(i, j);
        if (IS_ZERO(i, j))
            return;
        m_array[GET_IDX(i, j)] = element;
    }
    // 获取元素M_ij
    E get(int i, int j)
    {
        CHECK(i, j);
        if (IS_ZERO(i, j))
            return 0;
        return m_array[GET_IDX(i, j)];
    }

    // 获取数组元素A[k]对应方阵的下标i和j
    void getKIdx(int k, int &i, int &j)
    {
        assert(k >= 0 && k < m_capacity);
        if (!m_priority)
        {
            i = (k + 1) / 3 + 1;
            j = k - 2 * i + 3;
        }
        else
        {
            j = (k + 1) / 3 + 1;
            i = k - 2 * j + 3;
        }
    }
    // 打印方阵
    void printMatrix()
    {
        for (int i = 1; i <= m_dimension; i++)
        {
            for (int j = 1; j <= m_dimension; j++)
                std::cout << get(i, j) << ' ';
            std::cout << '\n';
        }
    }

    int getCapacity()
    {
        return m_capacity;
    }

    int getDimension()
    {
        return m_dimension;
    }
};

使用:

#include "diagonalMatrix.hpp"
int main()
{
    using namespace std;
    DiagonalMatrix<int> d(6);
    int matrix[6][6] =
        {
            {1, 1, 0, 0, 0, 0},
            {1, 1, 1, 0, 0, 0},
            {0, 1, 1, 1, 0, 0},
            {0, 0, 1, 1, 1, 0},
            {0, 0, 0, 1, 1, 1},
            {0, 0, 0, 0, 1, 1}};

    // set value
    int i, j, k;
    for (i = 0; i < 6; i++)
        for (j = 0; j < 6; j++)
            if (matrix[i][j] != 0)
                d.set(matrix[i][j], i + 1, j + 1);

    // get idx and value
    for (k = 0; k < d.getCapacity(); k++)
    {
        d.getKIdx(k, i, j);
        printf("k = %d , i = %d, j = %d , matrix[%d][%d] = %d\n", k, i, j, i, j, d.get(i, j));
    }
    d.printMatrix();
}

结果:

k = 0 , i = 1, j = 1 , matrix[1][1] = 1
k = 1 , i = 1, j = 2 , matrix[1][2] = 1
k = 2 , i = 2, j = 1 , matrix[2][1] = 1
k = 3 , i = 2, j = 2 , matrix[2][2] = 1
k = 4 , i = 2, j = 3 , matrix[2][3] = 1
k = 5 , i = 3, j = 2 , matrix[3][2] = 1
k = 6 , i = 3, j = 3 , matrix[3][3] = 1
k = 7 , i = 3, j = 4 , matrix[3][4] = 1
k = 8 , i = 4, j = 3 , matrix[4][3] = 1
k = 9 , i = 4, j = 4 , matrix[4][4] = 1
k = 10 , i = 4, j = 5 , matrix[4][5] = 1
k = 11 , i = 5, j = 4 , matrix[5][4] = 1
k = 12 , i = 5, j = 5 , matrix[5][5] = 1
k = 13 , i = 5, j = 6 , matrix[5][6] = 1
k = 14 , i = 6, j = 5 , matrix[6][5] = 1
k = 15 , i = 6, j = 6 , matrix[6][6] = 1
1 1 0 0 0 0
1 1 1 0 0 0
0 1 1 1 0 0
0 0 1 1 1 0
0 0 0 1 1 1
0 0 0 0 1 1

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

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

相关文章

chatgpt赋能python:Python文件夹的使用和优化

Python 文件夹的使用和优化 文件夹是计算机操作系统中最基本的存储单位之一。在计算机领域&#xff0c;文件夹也被称为目录。文件夹中可以存储多个文件或其他文件夹&#xff0c;使得文件在计算机中可以更好的组织和管理。基于Python语言&#xff0c;我们可以很容易地创建、读取…

javaEE基于springboot的小区社区文化活动报名系统jsp生活服务网站

社区文化宣传网站采用的开发框架为springboot框架&#xff0c;开发工具采用Eclipse&#xff0c;idea 服务器用的是Tomcat。编码语言是Java&#xff0c;数据库采用Mysql数据库。 本社区文化宣传网站&#xff0c;主要服务的用户是社区附近的居民&#xff0c;为居民展示最新的新闻…

带电更换10kV架空线路直线杆绝缘子(绝缘手套作业法)

一、现场复勘 1.核对线路及杆塔号 线路双重名称及杆号无误。 2.检查杆身质量 3.检查电杆埋深 4.检查拉线受力情况 5.检查相邻杆情况 作业点及相邻侧电杆之间导线应无断股等现象。 6.检查气象条件 作业前需进行湿度和风速的测量&#xff0c;风力大于5级&#xff0c;或湿度大…

5分钟搞定验证码

验证码生成 本效果是利用easy-captcha工具包实现&#xff0c;首先需要添加相关依赖到pom.xml中&#xff0c;代码如下&#xff1a; <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6…

链式二叉树高质量OJ—【Leedcode】

目录 ​编辑 1. 单值二叉树 题目 题目分析 代码实现 不带返回值版本 带返回值版本 递归展开图 2. 相同的树 题目 题目分析 代码实现 3. 对称二叉树 题目 题目分析 代码实现 4. 另外一颗子树 题目 题目分析 代码实现 递归展开图 5. 二叉树的前、中、后序遍…

给电脑重装系统有什么坏处吗

电脑重装系统是解决一些问题的常见方法&#xff0c;但是它也存在一些潜在的坏处。本文将为您详细介绍电脑重装系统的坏处&#xff0c;并提供一些注意事项&#xff0c;帮助您做出明智的决策。 工具/原料&#xff1a; 系统版本&#xff1a;Windows10 品牌型号&#xff1a;惠普…

涂鸦智能发布全球首款Matter+Alexa Built-in涂鸦智选智慧中控屏L

根据Parks Associates今年4月发布的《Next-Generation Smart Home: Building for the Future》显示&#xff0c;41%的美国互联网家庭拥有智能家居设备&#xff0c;越来越多的家庭正在部署全屋智能。 当家中出现越来越多的智能设备时&#xff0c;智慧中控屏&#xff0c;凭借“所…

行业报告 | AIGC应用与实践展望报告:人工智能重塑内容产业的作业模式

原创 | 文 BFT机器人 前言 Introduction 不可否认AIGC的出现似乎已经让大家预见了Al应用的拐点&#xff0c;其创造性与智能性一夜之间刷新了大众认知。但去伪存真&#xff0c;在市场火爆的背后其真正的应用及商业价值几何&#xff0c;更待我们冷静地剖析。 01 概念重生&#…

破解excel单元格保护

EI目录.xlsx 被保护&#xff0c;想查其中期刊&#xff0c;却不能直接复制。 step1.文件后缀改成.rarstep2.360压缩包打开&#xff0c;找到【sheet1.xml】step3.使用记事本打开&#xff0c;删除部分指定代码step4.后缀改回.xlsx 我是用360压缩包可以直接在.rar中 进行修改。 …

生态环境监测好帮手——便携式水污染物监测设备

便携式水污染物监测设备也可以称作便携式水质多参数检测仪 根据生态环境保护需要而专门研发的一款可快速准确测定地表水、地下水、城市污水及工业废水中CODcr、氨氮、总磷、总氮等50余种指标&#xff0c;浓度直读&#xff1b;可广泛用于水厂、食品、化工、冶金、环保及制药行业…

《机器人SLAM导航核心技术与实战》第1季:第5章_机器人主机

视频讲解 【第1季】5.第5章_机器人主机-视频讲解 【第1季】5.1.第5章_机器人主机_X86与ARM主机对比-视频讲解 【第1季】5.2.第5章_机器人主机_ARM主机树莓派3B-视频讲解 【第1季】5.3.第5章_机器人主机_ARM主机RK3399-视频讲解 【第1季】5.4.第5章_机器人主机_ARM主机Jetso…

chatgpt赋能python:Python文件大小函数:了解文件大小的方法和掌握文件操作技巧

Python文件大小函数&#xff1a;了解文件大小的方法和掌握文件操作技巧 文件大小是我们经常需要考虑的一个问题&#xff0c;无论是在计算机存储、文件上传、程序优化等场景中都需要关注。在Python中&#xff0c;我们可以通过文件操作函数来查询文件大小&#xff0c;这篇文章将…

看了两位阿里P10的成长经历,我的认知升华了

两位 P10 大佬的成长经历 相信不少人和我一样&#xff0c;对这些高段位大佬的成长经历有很强的好奇心&#xff0c;想知道他们是如何达到这一步的&#xff0c;这期间有什么关键的选择。这一节我们来看下他们的成长经历&#xff0c;通过了解前辈是如何成长的&#xff0c;可以帮助…

Oracle11G安装说明

Oracle11G安装说明 一、序二、安装安装依赖包基础环境配置安装Oracle 三、配置Oracle 一、序 Oracle和MySQL语法区别&#xff1a;https://blog.csdn.net/lanmuhhh2015/article/details/97763615 Oracle创建用户、角色、授权、建表&#xff1a;https://www.cnblogs.com/roger1…

chatgpt赋能python:Python散点图的颜色设置

Python散点图的颜色设置 什么是散点图&#xff1f; 散点图是一种数据可视化的图表类型。它用于观察两个变量之间的关系。通常&#xff0c;x轴表示一个变量&#xff0c;y轴表示另一个变量。每个点表示一个数据点&#xff0c;它在x和y轴上分别具有对应的值。我们可以通过比较散…

再获数千万元追加投资!宏景智驾B轮总融资已近「5亿元」

5月26日&#xff0c;宏景智驾&#xff08;Hyperview&#xff09;宣布获得阿美风险投资&#xff08;Aramco Ventures&#xff09;旗下多元化成长基金Prosperity7 Ventures数千万元的追加投资&#xff0c;这也是继2022年2月Prosperity7独家投资宏景智驾超亿元战略融资后又一次投出…

博途1200PLC由丝杠位移速度计算电机转速(moveVel_TO_motorSpeed功能块)

博途PLC 脉冲轴控制,功能块介绍请参看下面文章博客,这篇博客介绍实际组态、编程时的注意事项,仅供参考,受水平和能力所限文中难免有错误和不足之处,欢迎大家评论指出。 博途1200PLC轴控功能块(脉冲轴)_西门子1200可以总线控制伺服么_RXXW_Dor的博客-CSDN博客STRUCT// 轴使…

查询物流不再困难——教您一招批量查询物流信息很管用

在物流行业&#xff0c;快递批量查询高手是一款必备工具。这款软件如同瑞士军刀一样&#xff0c;可以解决许多查询和管理工作中的难题。让我们一起来探讨一下快递批量查询高手的背景、需求、实现方案、功能特点以及应用案例&#xff0c;以了解它的重要性以及实用性。 首先&…

chatgpt赋能python:Python文件所在目录

Python文件所在目录 什么是Python文件所在目录&#xff1f; 在Python编程中&#xff0c;文件所在目录指的是存储Python代码文件的文件夹。该文件夹包含所有Python代码文件&#xff0c;这些文件可以包含函数、类、变量等。 如何查找Python文件所在目录&#xff1f; Python文…

Python类的属性和方法介绍

Python类的属性和方法介绍 本文主要讲python类属性&#xff08;类变量&#xff09;、实例属性&#xff08;实例变量&#xff09;&#xff1b;类方法、静态方法、实例方法。 【定义在类中的变量也称为属性&#xff0c;定义在类中的函数也称为方法。】 这些都是Python面向对象…