提问人:2Napasa 提问时间:8/5/2022 最后编辑:2Napasa 更新时间:8/7/2022 访问量:198
对称带矩阵向量乘法
Symmetric band matrix vector multiplication
问:
尝试将对称带矩阵乘以向量,即简单乘法
A*x = b
其中 A 是对称带矩阵,存储格式如下。因此,它的下半部分不会保存到存储中。
cols
是包含非零波段索引的向量,例如 是主对角线,是位于主对角线 +1 位移处的上轨带,cols(1,1)=1
cols(1,2)=2
第二行是条带的长度,这个值是常数,我最初存储它是为了得到矩阵大小。cols
代码的第一部分
读取文件,将表格转换为二维数组
生成随机向量来测试结果
x
将对称能带形式转换为正则矩阵,目的与上述相同
所以这个想法是采用时间向量并做元素明智的乘积。
比如说,将矩阵主对角线的每个元素与相应的向量元素相乘,然后递增 rhs 向量。x
b
对于移位的波段,我对向量进行切片并增加相应的x
b
我设法将上面的三角形乘以向量,差值为零x
max(abs(triu(asps)*x-b))
但是当我尝试对下矩阵部分进行乘法时,max(abs(asps*x-b)) 给出了一些错误。
可能是什么问题?也许索引是错误的?
错误应该在上乘法之后或当我将数组切成时包含的行的某个地方b(i+width)
x
xTimesLower
clc; clear; close all;
adnsT = readtable('C:\Users\user\Documents\denseCTAC.txt','ReadVariableNames', false);
cols = [1 2 3 9 10 11 19;...
81 80 79 73 72 71 63];
adns = table2array(adnsT);
n = 81;
for i = 1:7
len = cols(2,i);
colShift = cols(1,i)-1;
for j = 1:len
asps(j,j+colShift)=adns(j,i);
end
end
asps = asps' + asps - eye(n).*diag(asps);
% spy(asps);
x = rand(n);
x = x(:,1);
b = x*0;
for j = 1:7
width = cols(1,j)-1;
for i = 1:n-width
if width == 0
b(i) = b(i)+adns(i,1)*x(i);
else
xTimesUpper = x(1+width:n);
xTimesLower = x(1:n-width);
%%%% multiplying upper part
b(i) = b(i) + adns(i,j)*xTimesUpper(i); % OK if compared to triuA*x-b
%%%% multiplying lower part
% b(i+width) = b(i+width) + adns(i,j)*xTimesLower(i); % shift issue?
end
end
end
max((asps)*x-b)
fprintf("Error=%d\n",max(abs(asps*x-b)));
答:
1赞
2Napasa
8/7/2022
#1
看起来代码正在工作 刚刚在整数矩阵上测试,差值为零,
由于浮点加法的非关联性,double 类型的结果相差 10^-14 到 10^-15
在整数代码大小写下方
clc; clear; close all;
adnsT = readtable('denseCTAC.txt','ReadVariableNames', false);
cols = [1 2 3 9 10 11 19;...
81 80 79 73 72 71 63];
adns = floor(table2array(adnsT)*100);
n = 81;
for i = 1:7
len = cols(2,i);
colShift = cols(1,i)-1;
for j = 1:len
asps(j,j+colShift)=adns(j,i);
end
end
asps = asps' + asps - eye(n).*diag(asps);
% spy(asps);
x = randi(10,n);
x = x(:,1);
b = x*0;
% x = x';
for j = 1:7
width = cols(1,j)-1;
for i = 1:n-width
if width == 0
b(i) = b(i)+adns(i,1)*x(i);
else
xTimesUpper = x(1+width:n);
xTimesLower = x(1:n-width);
%%%% multiplying upper part
b(i) = b(i) + adns(i,j) * xTimesUpper(i); % OK if compared to triuA*x-b
b(i+width) = b(i+width) + adns(i,j)*xTimesLower(i);
%%%% multiplying lower part
% b(i+width) = b(i+width) + adns(i,j)*xTimesLower(i); % shift issue?
end
end
end
% max(triu(asps)*x-b)
max(abs(asps*x-b))
% fprintf("Error=%d\n",max(abs(asps*x-b)));
评论