稀疏技术——使用MATLAB编写

2023-11-19

稀疏技术——使用MATLAB编写

导读

本文源于武老师电力系统仿真课程的其中一个作业。
了解 SPICE的同学可能知道SPICE(SimulationProgram with Integrated Circuit Emphasis)使用的六项技术[改进的节点分析法(ModifiedNodal Analysis),稀疏矩阵解法(Sparse Matrix Solver),牛顿-拉夫逊迭代(Newton-RaphsonIteration),隐性数值积分(ImplicitNumerical Integration),动态步长的瞬态分析(Dynamic Time Step Control),局部截断误差(LocalTruncation Error)]奠定了当代电路仿真软件的基石,而武老师对这六个方面都有详细介绍,所以个人认为即使志不在电力系统,武老师的课程也是个极为有用的课程,对我们理解所有电路仿真软件都有作用。
程序采用MATLAB进行编写。详细的原理性介绍这里不再赘述,可以参考这位师兄的文章:稀疏技术

核心思想

在这里稀疏矩阵采用散居存储。笔者的程序中核心思想有两个:

  1. 将散居存储得到的三个数组合并于一个矩阵,如矩阵第一行存储非零元素的值,第二行存储非零元素在原矩阵中的行号,第三行存储非零元素在原矩阵中的列号。
  2. MATLAB中find函数的应用。如定义一个有三行的矩阵Matrix,那么代码
    [xp,yp]=find(Matrix(2,:)==p);
    可以找到Matrix第二行中所有值等于p的元素,并且返回这些元素在Matrix中的行、列号并且存储在数组xp和yp中。

具体代码

  1. 对数据采用散居存储
    考虑到电力系统导纳矩阵的对称性,只存储对角线和上三角元素即可,并且将非零元素的行列号以及值存储在一个三行矩阵Matrix中。
  2. 因子表分解
    首先寻找Matrix(2,:)中存储着的第i行的非零元素,并且返回该非零元素在Matirx的位置存储在yr数组中;
    接下俩进行因子表分解:
    首先进行规格化计算:根据存储着非零元素在Matrix矩阵第二行的位置的yr数组,可以找到第i行的所有非零元素,然后将非对角线元素值除以该行的对角线线元素值。
    然后接着进行消去计算:
    先对末端节点自边值进行消去计算(最根本的思想就是利用行号=列号这个条件寻找到末端节点的自边值)。
    在这里插入图片描述
    然后对互边进行消去计算。
    在这里插入图片描述
    如果两个末端节点之间不存在边,则需要新增边,即会新出现非零元素,将非零元素直接插到Matrix最后即可。
  3. 前代计算
    在这里插入图片描述
    根据图片中的通式编写程序即可。
  4. 规格化计算
    在这里插入图片描述
    同样根据图片中的通式编写程序即可。
  5. 回代计算
    在这里插入图片描述
    同样根据图片中的通式编写程序即可。

完整代码如下所示:

%% M为传入的矩阵
%  M = [[2,0,0,0,0,0,1,0,0,0,0,1]
%       [0,2,0,0,1,0,0,0,1,0,0,0]
%       [0,0,2,0,0,1,0,0,1,0,0,0]
%       [0,0,0,2,0,0,1,0,0,1,0,0]
%       [0,1,0,0,2,0,0,0,0,0,0,1]
%       [0,0,1,0,0,2,0,0,0,1,0,0]
%       [1,0,0,1,0,0,2,0,0,0,0,0]
%       [0,0,0,0,0,0,0,2,1,0,1,0]
%       [0,1,1,0,0,0,0,1,2,0,0,0]
%       [0,0,0,1,0,1,0,0,0,2,1,0]
%       [0,0,0,0,0,0,0,1,0,1,2,1]
%       [1,0,0,0,1,0,0,0,0,0,1,2]];
%  B = [4;4;4;4;4;4;4;4;5;5;5;5];
 
function Task1(M,B)
[row,column]=size(M); % 获取矩阵M的行数row,列数column
fprintf('注意结算结果是基于对称矩阵情况下计算的\n')
%% 数据采用散居存储,考虑到矩阵对称性,只存储对角线和上三角元素
row_num=[]; % 用来存放非零元素的行号
column_num=[]; % 用来存放非零元素的列号
value=[]; % 用来存放非零元素的值
for i=1:row
    for j=i:column
        if(M(i,j)~=0) 
           value=[value M(i,j)];
           row_num=[row_num i];
           column_num=[column_num j];
        end
    end
end
M=[]; % 释放矩阵M占用的存储空间
% 三者组合成一个矩阵
%1行为非零元素值,第2行为非零元素行号,第3行为非零元素列号
Matrix=[value;row_num;column_num];
value=[];row_num=[];column_num=[]; % 释放内存
%% 因子表分解
for i=1:row
    % 输出行数=i的元素在row_num中的位置,y_r为列号
    [~,yr]=find(Matrix(2,:)==i); 
    c_yr=length(yr); % 得到yr数组的大小
    % 规格化计算
    if c_yr>=2
        for j=2:c_yr
            Matrix(1,yr(j))=Matrix(1,yr(j))/Matrix(1,yr(1));
        end
        % 自边的消去计算
        for j=2:c_yr
           % 寻找末端节点自边值的位置
           % 行号和列号相等的点即为末端节点自边值
           p=Matrix(3,yr(j)); % 得到列号
           [~,yp]=find(Matrix(2,:)==p);
           % 末端节点自边值的消去计算
           len_yp=length(yp);
           for b=1:len_yp
               if (Matrix(3,yp(b))==p)
                   Matrix(1,yp(b))=Matrix(1,yp(b))-Matrix(1,yr(j))^2*Matrix(1,yr(1));
               end
           end
        end
        % 互边的消去计算
        if c_yr>=3 % 末端节点在2个以上时,末端节点之间的互边才需要改变或者新增
            for j=2:c_yr
                for k=1:(c_yr-j)
                    % 依次取末端节点任意两条边的列号
                    p1=Matrix(3,yr(j)); 
                    p2=Matrix(3,yr(j+k)); 
                    % 保证边的方向都是编号小的指向编号大的
                    if (p1>=p2) 
                       temp=p1;
                       p1=p2;
                       p2=temp;
                    end
                    % 先查找M(p1,p2)是不是非零元素
                    % 若是非零元素,则直接在Matrix中修改值的大小
                    % 若不是非零元素,则需要新增非零元素在Matrix矩阵中
                    [~,yp1]=find(Matrix(2,:)==p1); % 找到行号为p1的所有非零元素
                    len_yp1=length(yp1); % 得到数组yp1的长度
                    flag=0; % 用来指示两个末端节点之间是否存在边
                    for a=1:len_yp1
                        if (Matrix(3,yp1(a))==p2) 
                           % 两个末端节点之间存在边,则进行修改
                           Matrix(1,yp1(a))=Matrix(1,yp1(a))-Matrix(1,yr(j))*Matrix(1,yr(j+k))*Matrix(1,yr(1));
                           flag=1; % 两个末端节点之间存在边
                           break
                        end
                    end
                    if (flag==0) % 两个末端节点之间不存在边,会新增边
                        temp2=0-Matrix(1,yr(j))*Matrix(1,yr(j+k))*Matrix(1,yr(1));
                        len=length(Matrix(1,:));
                        Matrix(1,len+1)=temp2;
                        Matrix(2,len+1)=p1;
                        Matrix(3,len+1)=p2;
                    end
                end
            end
        end
    end
end
% 得到因子分解表矩阵
D=eye(row);
U=eye(row);
L=eye(row);
temp1=[];
for i=1:length(Matrix(1,:))
    if (Matrix(2,i)==Matrix(3,i))
        temp1=[temp1 Matrix(1,i)];
    else
        U(Matrix(2,i),Matrix(3,i))=Matrix(1,i);
        L(Matrix(3,i),Matrix(2,i))=Matrix(1,i);
    end 
end
for i=1:row
    D(i,i)=temp1(i); 
end
% 对因子表结果进行显示
fprintf('D=');disp(D);
fprintf('U=');disp(U);
%% 前代计算
z=ones(row,1);
temp3=0;
for i=1:row
    for j=1:(i-1)
        [~,yj]=find(Matrix(2,:)==j); % 找到第j行的所有非零元素
        for k=1:length(yj)
            if (Matrix(3,yj(k))==i) % Matrix中存在坐标为(j,i)的非零元素,则进行计算,否则不计算
                temp3=temp3+Matrix(1,yj(k))*z(j,1); 
            end
        end
    end
    z(i,1)=B(i,1)-temp3;
    temp3=0;
end
%% 规格化计算
y=ones(row,1);
for i=1:row
    [~,yi]=find(Matrix(2,:)==i); % 找到第i行的所有非零元素
    for j=1:length(yi)
        if (Matrix(3,yi(j))==i) % 找到对角元元素
           y(i,1)=z(i,1)/Matrix(1,yi(j)); 
        end
    end
end
%% 回代计算
x=ones(row,1);
temp3=0;
for i=1:row
    j=row-i+1;
    for k=(j+1):row
        [~,yj]=find(Matrix(2,:)==j); % 找到第j行的所有非零元素
        for g=1:length(yj)
            if (Matrix(3,yj(g))==k)
                temp3=temp3+Matrix(1,yj(g))*x(k);
            end
        end
    end
    x(j,1)=y(j,1)-temp3;
    temp3=0;
end
fprintf('解x的结果为x=\n');disp(x);
end

结果

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

稀疏技术——使用MATLAB编写 的相关文章

  • 如何将数据传递给 MATLAB oncleanup 函数?

    我有一个编译好的 matlab 程序 可以自动调整机器参数 在调整周期结束时 我需要恢复一些原始设置 有时会发生意外错误 有时用户会发现调整算法未正常工作 因此应终止 使用 control C 如果发生可预测的错误 我可以使用 try ca
  • 将 kinect RGB 和深度值转换为 XYZ 坐标

    我正在寻找一种简单的方法将 kinect RGB 和深度值转换为 XYZ 坐标 使用 MATLAB 我的目标是一个输入为以下内容的函数 每个点的 RGB 和深度值Kinect相机 并输出 每个点的 x y 和 z 值 RGB 深度 RGB
  • 通过多次合并相同的行向量来构建矩阵

    有没有一个matlab函数可以让我执行以下操作 x 1 2 2 3 然后基于x我想建立矩阵m 1 2 2 3 1 2 2 3 1 2 2 3 1 2 2 3 您正在寻找REPMAT http www mathworks com help t
  • 在 MATLAB 中绘图后恢复轴

    从文本文件绘制多种方法的输出后 未显示轴的右侧和上侧 我需要拥有它们并将它们加粗 就像当前的轴一样 绘制的数据来自存储每种方法数据的文件 每个数据文件都是一个 256x2 文件 包含 0 1 之间的值 第一列是精度 第二列是召回率 figu
  • MATLAB:将当前文件夹设置为脚本位置

    我在不同的文件夹中有一些脚本和数据 我使用addpath和相对路径经常 我的问题是 只有当我的当前文件夹是我执行的脚本所在的位置时 这才有效 例如 如果我执行添加路径 X 的脚本 A 然后执行位于路径 X 中的脚本 B 则 Matlab 不
  • 如何在 MATLAB 中将矩阵元素除以列总和?

    有没有一种简单的方法可以将每个矩阵元素除以列和 例如 input 1 4 4 10 output 1 5 4 14 4 5 10 14 以下是执行此操作的不同方法的列表 使用bsxfun https www mathworks com he
  • Matlab:2行10列的子图

    如何在 matlab 中绘制 20 幅图像 2 行 10 列 我知道我必须使用 子图 功能 但我对给出的参数感到困惑 我尝试给予 子图 2 10 行索引 列索引 但它似乎不起作用 请帮忙 的前两个参数subplot函数分别给出图中子图的总行
  • 优先连接,Matlab 中的复杂网络

    大家好 我现在正在 MATLAB 中研究优先附件模型 在理解以下内容时遇到一些困难 假设我一开始有 4 个节点 连接如下 time 0 1 lt gt 2 3 lt gt 4 在下一个时间步骤中 我添加一个节点和 4 个连接 然后添加另一个
  • MATLAB parfor 和 C++ 类 mex 包装器(需要复制构造函数?)

    我正在尝试使用概述的方法将 C 类包装在 matlab mex 包装器中here http www mathworks com matlabcentral newsreader view thread 278243 基本上 我有一个初始化
  • 霍夫变换检测和删除线

    我想使用霍夫变换检测图像中的线条 但是我不想绘制线条 而是想删除原始图像中检测到的每条线条 image imread image jpg image im2bw image BW edge image canny imshow BW fig
  • 在 Python 上显示 Matlab mat 文件中的图像

    我目前正在尝试显示从此下载的 Mat 文件中的图像site http www rctn org bruno sparsenet 这是一个 mat 文件 所以我尝试使用 scipy io loadmat 函数加载它 但我似乎无法绘制图像 我究
  • 如何在matlab中使矩阵图平滑

    就像上图一样 怎样才能让画面更流畅呢 或者缩小y轴的范围 数据来自二维矩阵 然后我用plot data 请随意提出任何想法 平滑线条的一种方法涉及样本点之间数据的非线性插值 当你这样做时plot x y o http www mathwor
  • 计算给出数组中最小标准差的子集

    让我们有一个大小的向量N 例如 x rand N 1 我想计算长度子集的最小标准差K在向量中 When N and K很小 很容易找到最好的子集 因为我可以使用nchoosek N K 枚举所有可能的子集 但是当值N and K比我们说的要
  • Matlab 中的 3D 堆叠条形图

    我想在一个图中绘制多个堆叠条形图 detached 条形图 例如 准确地想象一下bar http mathworks com help matlab ref bar3 detached png绘图 但堆叠在一起 而不是单一颜色 Set up
  • 在 Matlab/Java 中将手部运动建模为 3D 曲线

    我只需要一些关于我遇到的问题 在哪里查看等的指导 我在我的一个项目中使用了运动跟踪手套 它返回每个手指和手掌的 X Y 和 Z 值 我想做的是首先根据这些坐标创建每个手指运动的表示 然后将它们每个附加到手掌的运动 以获得手的表示 一旦我完成
  • 使用正常数据直方图与直接公式进行熵估计(matlab)

    假设我们已经绘制了n 10000标准正态分布的样本 现在我想使用直方图计算其熵来计算概率 1 计算概率 例如使用matlab p x hist samples binnumbers area x 2 x 1 sum p p p area b
  • 可以避免迭代元胞数组时的“s{1} 烦恼”吗?

    The s 1 标题的 烦恼 指的是下面的 for 块中的第一行 for s some cell array s s 1 unpeel the enclosing cell do stuff with s end This s s 1 业务
  • 如何调整x轴和y轴的大小

    如何调整 x 轴和 y 轴的大小 我想要什么 更具体 3900 60 30 0 60 120 180 3600 我做了什么 a 0 0 1 10000 plot a 我应该写什么才能按预期调整 x 和 y 轴的大小 EDIT 我不想 390
  • OpenCV功能类似于matlab的“查找”

    我正在寻找 openCV 中的一个函数来帮助我制作图像蒙版 例如在 MATLAB 中 B A or B 零 大小 A B A 10 c 有些功能可以让你通过mask向他们提出论据 按照您描述的方式创建面具 我认为您正在追求Cmp 或 Cmp
  • 如何从一个清晰的例子计算二维图像中的吉布斯能量

    我有一个关于矩阵的有趣问题 在吉布斯分布中 吉布斯能量U x 可以计算为 这是所有可能的派系 C 上的派系势 Vc x 的总和 右图 团 c 被定义为 S 中站点的子集 x 蓝色像素的邻域是左图中黄色像素的邻居 其中每对不同的站点都是邻居

随机推荐

  • 用虚幻4开发搭积木的VR游戏

    2016 年 9 月 23 24 日 由 CSDN 和创新工场联合主办的 MDCC 2016 移动开发者大会 中国 Mobile Developer Conference China 将在北京 国家会议中心召开 来自iOS Android
  • 如何创建一个Windows软件

    很久以前我创造了一个Windows软件 我今天把这个方法分享给大家 我的系统 Edition Windows 11 Pro Insider Preview Version 22H2 Installed on 7 30 2022 OS bui
  • 掘金个人主页头像旋转效果

    img src https sf1 ttcdn tos pstatp com img user avatar d1d3c1b115358ea70f51edcd697b58b2 300x300 image alt 钱端挖掘机师傅的个人资料头像
  • 服务器cpu最多几核心,决定虚拟服务器所需要的CPU核心数量是一件非常复杂的事情...

    决定虚拟服务器所需要的CPU核心数量是一件非常复杂的事情 但是综合考虑下面几个因素 相信管理员能够作出最适合于自己的决定 看起来决定虚拟服务器所需要的单颗CPU核心数量是一件非常简单的事情 但事实上有很多复杂因素需要考虑 首先 在虚拟环境C
  • ES索引库的别名的使用--不停服实现索引库的重建切换

    ES 的别名不停停服切换索引 线上发布 场景 我们现在线上正在使用 ES索引库 V 没有使用ES索引库别名 两个问题 现在由于字段更新 把线上的数据重新写入了V1库 现在如何在不断服的情况下 完美的实现 从V 切换到V1 索引库 后续如果再
  • 我的世界 服务器文件ess,求助服务器ess插件报错怎么解

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 12 54 56 ERROR Could not pass event PlayerInteractEvent to Essentials v2 15 0 52 java lang NoSuch
  • 以AI学AI系列——不懂就问(一)

    1 问 如果我想实现一个小型的类似chatGpt的应用 能够理解我输入的语音 我需要怎么做 回答 Based on your latest question it seems that you are interested in train
  • [图像处理]边缘提取以及Harris角点检测

    在本周的计算机视觉与模式识别作业中 给定输入图像是两张普通A4打印纸 上面可能有手写笔记或者打印内容但是拍照时角度不正 要求输出 1 图像的边缘 2 计算 A4纸边缘的各直线方程 3 提取A4纸的4个角点 作业要求的是使用C 的CImg库
  • Android系统启动流程,从init.rc 到 launcher 加载过程分析

    Android系统启动流程 从init rc 到 launcher 启动过程分析 目录 1 zygote 启动分析 1 1 init进程的入口函数 1 2 解析init rc 1 3 app main cpp 解析zygote启动参数 1
  • 传统IO与零拷贝

    传统IO 传统的 I O 数据传输是指在计算机系统中 使用输入 输出 I O 操作进行数据传输的一种方式 这种方式通常涉及将数据从内存传输到外部设备 如磁盘 网络等 或从外部设备传输到内存 传统的 I O 数据传输通常采用阻塞式的方式 即在
  • C# 4.0的一些新特性

    vs2010正式版4月12日发布了 前几天我也下了一个 但这几天都没有时间好好试用一下 今天针对C 语言的新特性使用了一下 感觉还不错 有几个新特性和大家分享一下 希望我没有太火星 一 新关键词 dynamic 在新版本的C 中 dynam
  • 【尚硅谷】SSM框架之SSM学习笔记

    MyBatis MyBatis简介 MyBatis历史 MyBatis最初是Apache的一个开源项目iBatis 2010年6月这个项目由Apache Software Foundation迁移到了Google Code 随着开发团队转投
  • rust + ffmpeg + sdl2 视频播放器,用纯RUST实现音视频流媒体服务

    Rust是一门系统编程语言 专注于安全 尤其是并发安全 支持函数式和命令式以及泛型等编程范式的多范式语言 RTMP协议确实复杂 在做这个项目之前 看过很多帖子 看过官方文档 但总是感觉不能彻底的理解清楚 在实现过一遍此协议之后 感觉清楚了不
  • 浅谈以太坊智能合约的设计模式与升级方法

    浅谈以太坊智能合约的设计模式与升级方法 1 最佳实践 2 实用设计案例 2 1 控制器合约与数据合约 1 gt 1 2 2 控制器合约与数据合约 1 gt N 2 3 控制器合约与数据合约 N gt 1 2 4 控制器合约与数据合约 N g
  • SpringBoot整合Mybatis-plus实现多级评论

    在本文中 我们将介绍如何使用SpringBoot整合Mybatis plus实现多级评论功能 同时 本文还将提供数据库的设计和详细的后端代码 前端界面使用Vue2 数据库设计 本文的多级评论功能将采用MySQL数据库实现 下面是数据库的设计
  • [学习记录]Flask会话维护

    前置知识 1 http是一种无状态的通信协议 本身不保存通信状态 2 web服务器本质上负责接收用户的请求 request 并按照规则给予用户响应 response 3 会话 session 是web服务器用来管理用户的一种方式 在一次会话
  • 图像描述算法排位赛:SceneXplain 与 MiniGPT4 谁将夺得桂冠?

    如果你对图像描述算法的未来感到好奇 本场 图像描述算法排位赛 绝对是你不能错过的 在这场较量中 SceneXplain 和 MiniGPT 4 将会比试 谁将摘得这场比赛的桂冠 背景介绍 在上篇文章中 我们介绍了图像描述 Image Cap
  • List[Bean]与jsonArray字符串的相互转换

    List User 与jsonArray字符串的相互转换 object testo725 def main args Array String Unit val lili User User lili 15 val tom User Use
  • Windows基础命令

    一 目录和文件的应用操作 1 cd命令 cd d d 切换d盘目录 因为改变了驱动器 所有需要加上 d 选项 cd c 如果没有改变驱动器号 就不需要加 d 选项 目录分为相对路径和绝对路径 相对路径 以当前为起点 代表的是当前路径 代表的
  • 稀疏技术——使用MATLAB编写

    稀疏技术 使用MATLAB编写 导读 核心思想 具体代码 结果 导读 本文源于武老师电力系统仿真课程的其中一个作业 了解 SPICE的同学可能知道SPICE SimulationProgram with Integrated Circuit