我正在将相同的二进制文件读入Python和Matlab并将其放入矩阵中。当我采用这个矩阵的范数时,我会得到不同的结果。
我正在使用相应的smatload函数来加载二进制文件。
的Python:
def smatload(filename):
#print 'opening: ', filename
f = open(filename, 'rb')
m = np.fromfile(f,'q',1)
n = np.fromfile(f,'q',1)
nnz = np.fromfile(f,'q',1)
print 'reading %d x %d with %d non-zeros' % (m,n,nnz)
S = np.fromfile(f,'d',3*nnz)
f.close()
S = S.reshape((nnz,3))
rows = S[:,0].astype(int) - 1
cols = S[:,1].astype(int) - 1
vals = S[:,2]
return csr_matrix((vals,(rows,cols)),shape=(m,n))
Matlab的:
function [A] = smatload(filename)
fid = fopen(filename,'r');
if( fid == -1 )
disp(sprintf('Error: Unable to open file [%s], fid=%d\n',filename,fid));
A = [-1];
fclose(fid);
return;
end
m = fread(fid,[1 1],'uint64');
n = fread(fid,[1 1],'uint64');
nnz = fread(fid,[1 1],'uint64');
fprintf('Reading %d x %d with %d non-zeros\n',m,n,nnz);
S = fread(fid,[3 nnz],'double');
fclose(fid);
A = sparse(S(1,:)',S(2,:)',S(3,:)',m,n);
我得到的返回矩阵规范的结果是
Matlab:规范(A。'来回')= 0.018317077159881
Python:np.linalg.norm(A)= 0.018317077159760
我已经确认他们正在读取正确数量的值(6590x7126矩阵,122526个非零),并且我对两者使用相同的标准(frobenius)。
关于可能导致这种情况的任何想法?
答案 0 :(得分:4)
快速浏览Frobenius Norm表明它需要对所有值进行平方并将它们加在一起。
由于你在read命令中有uint64,看起来你可能正在填充浮点存储。当您将两个二进制数相乘时,需要两倍的位来存储答案。这意味着您需要128位来存储所有十进制值。如果Python和MATLAB以不同的方式执行此操作,则可以解释为什么您的十进制值不同。
有关MATLAB和Python如何处理浮点精度的信息,请参阅这两个链接:
的Python: https://docs.python.org/2/tutorial/floatingpoint.html
MATLAB: http://blogs.mathworks.com/cleve/2014/07/07/floating-point-numbers/
答案 1 :(得分:2)
Matlab肯定似乎对稀疏和密集阵列有不同的实现。使用4425x7126稀疏矩阵A和您链接到的54882非零条目以及以下命令:
FA=full(A);
av=A(:);
fav=FA(:);
我希望以下命令都能产生相同的值,因为它们都计算A的(非零)元素的平方和的平方根:
norm(A,'fro')
norm(av,2)
norm(FA,'fro')
norm(fav,2)
sqrt( sum(av .* av) )
sqrt( sum(av .^ 2) )
sqrt( sum(fav .* fav) )
sqrt( sum(fav .^ 2) )
事实上,我们看到三个略有不同的答案:
norm(A,'fro') 0.0223294051001499
norm(av,2) 0.0223294051001499
norm(FA,'fro') 0.0223294051001499
norm(fav,2) 0.0223294051001499
sqrt( sum(av .* av) ) 0.0223294051001521
sqrt( sum(av .^ 2) ) 0.0223294051001521
sqrt( sum(fav .* fav) ) 0.0223294051001506
sqrt( sum(fav .^ 2) ) 0.0223294051001506
事实上,即使报告的A的稀疏和密集表示的元素总和(有点)也不同:
sum(A(:)) 1.00000000000068
sum(FA(:)) 1.00000000000035
这些差异似乎与您在Python和Matlab规范之间看到的数量级相同。
答案 2 :(得分:1)
不是答案,但我没有足够的代表发表评论。尝试将问题缩小一点是否值得?如果将原始矩阵划分为4个子矩阵(左上角,右上角,左下角,右下角),并将Matlab和Python中报告的Frobenius范数与每个子矩阵进行比较,您是否仍然看到任何值之间存在差异?如果是,则冲洗并重复该子标准。如果不是,那么请不要浪费时间阅读这篇评论。 :-)