Arrays 在Matlab上从二进制文件读取稀疏数组
我必须编写一个函数,从一个Arrays 在Matlab上从二进制文件读取稀疏数组,arrays,matlab,Arrays,Matlab,我必须编写一个函数,从一个二进制文件(.dat)中读取一个二维双精度数组,该文件在一个列中结构化,其名称由函数的单输入参数提供。该文件的格式如下所示: 首先,有两个uint32编号,对应于数组的行数和列数。之后,有一个双倍数,即数组中非零元素的数量。然后,数组中的每个非零元素由文件中的两个uint32标量和一个双标量表示,顺序如下:行索引(uint32)、列索引(uint32)和值(double)。例如: 5 4 2 1 1 8 2 2 9 这意味着数组有5行4列,总共有2个非零元素。这些元素
二进制文件(.dat)
中读取一个二维双精度数组,该文件在一个列中结构化,其名称由函数的单输入参数提供。该文件的格式如下所示:
首先,有两个uint32编号,对应于数组的行数和列数。之后,有一个双倍数,即数组中非零元素的数量。然后,数组中的每个非零元素由文件中的两个uint32标量和一个双标量表示,顺序如下:行索引(uint32)、列索引(uint32)和值(double)。例如:
5
4
2
1
1
8
2
2
9
这意味着数组有5行4列,总共有2个非零元素。这些元素位于位置(1,1)
(值为8)和位置(2,2)
(值为9)。所有其他元素都等于0。因此,阵列将是:
8 0 0 0
0 9 0 0
0 0 0 0
0 0 0 0
0 0 0 0
函数必须返回从文件中读取的二维数组作为输出参数,如果打开文件时出现问题,函数将返回空数组。目前,我已尝试使用以下代码:
function A = sparse_array_in( filename )
fid = fopen( filename,'rt' );
if fid < 0
A = [];
return;
end
% Get total number of elements on the file
n = 0;
while (fgets(fid) ~= -1),
n = n+1;
end
% Close then reopen
fclose(fid);
fid = fopen( filename,'rt' );
% Read size of array and number of non-zero elements
rows = fread( fid,1,'uint32' );
cols = fread( fid,1,'uint32' );
dims = [ rows,cols ];
non_zero = fread( fid,1,'uint32' );
% Create array of zeros
A = zeros( dims );
% Fill array A with the values from the file
for i = 1:non_zero
r = fread( fid,1,'uint32' );
c = fread( fid,1,'uint32' );
v = fread( fid,1,'double' );
A(r,c) = v;
end
fclose( fid );
end
函数A=sparse\u array\u in(文件名)
fid=fopen(文件名,'rt');
如果fid<0
A=[];
返回;
结束
%获取文件上的元素总数
n=0;
而(fgets(fid)~=-1),
n=n+1;
结束
%关闭然后重新打开
fclose(fid);
fid=fopen(文件名,'rt');
%读取数组大小和非零元素数
行=fread(fid,1,'uint32');
cols=fread(fid,1,'uint32');
dims=[行,列];
非零=fread(fid,1,'uint32');
%创建零数组
A=零(dims);
%用文件中的值填充数组A
对于i=1:非零
r=fread(fid,1,'uint32');
c=fread(fid,1,'uint32');
v=fread(fid,1,'double');
A(r,c)=v;
结束
fclose(fid);
结束
但它似乎不起作用。我遗漏了什么?您的代码存在一些问题:
a
的任务后立即粘贴一条return
语句:
if fid < 0
A = [];
return;
end
A =
1 0 0 0 0 0 0
0 2 0 0 0 0 0
0 0 3 0 0 0 0
0 0 0 4 0 0 0
0 0 0 0 0 0 0
fread
对。第二个参数告诉您要读入多少特定类型的数字。您正在使用1、2或3,这意味着您正在读取特定类型的1、2或3个数字。因为您使用fread
读取每次呼叫的单个号码,所以它们都应该为1。此外,确定行的总数对我来说似乎是多余的。如果给定了非零元素的总数,为什么还要费心计算有多少行呢?您已经知道有多少个非零元素,所以只需从1迭代到尽可能多的非零数字。因此,请尝试以下方法:
% Read size of array and number of non-zero elements
rows = double(fread( fid,1,'uint32' )); %// Change
cols = double(fread( fid,1,'uint32' )); %// Change
dims = [ rows,cols ];
non_zero = fread( fid,1,'uint32' ); %// Change
% Create array of zeros
A = zeros( dims );
% Fill array A with the values from the file
for i = 1 : non_zero %// Change
r = fread( fid,1,'uint32' ); %// Change
c = fread( fid,1,'uint32' ); %// Change
v = fread( fid,1,'double' ); %// Change
A(r,c) = v;
end
%A = reshape( A,dims' ); %// Why are you reshaping?
fclose( fid );
因此,根据上述注释,您的代码如下所示:
function A = sparse_array_in( filename )
fid = fopen( filename,'rt' );
if fid < 0
A = [];
return; %// Change
end
% Read size of array and number of non-zero elements
rows = fread( fid,1,'uint32'); %// Change
cols = fread( fid,1,'uint32'); %// Change
dims = [ rows,cols ];
non_zero = fread( fid,1,'uint32' ); %// Change
% Create array of zeros
A = zeros( dims );
% Fill array A with the values from the file
for i = 1:non_zero
r = fread( fid,1,'uint32' ); %// Change
c = fread( fid,1,'uint32' ); %// Change
v = fread( fid,1,'double' ); %// Change
A(r,c) = v;
end
%// Change - remove reshape
fclose( fid );
end
这是一个5 x 7的矩阵,其中(1,1)=1,(2,2)=2,(3,3)=3,(4,4)=4
,具有4个非零值。我创建了一个二进制文件,然后使用上面修复的函数来获得结果:
fid = fopen('sparse_binary.dat', 'w');
fwrite(fid, 5, 'uint32');
fwrite(fid, 7, 'uint32');
fwrite(fid, 4, 'uint32');
fwrite(fid, 1, 'uint32');
fwrite(fid, 1, 'uint32');
fwrite(fid, 1, 'double');
fwrite(fid, 2, 'uint32');
fwrite(fid, 2, 'uint32');
fwrite(fid, 2, 'double');
fwrite(fid, 3, 'uint32');
fwrite(fid, 3, 'uint32');
fwrite(fid, 3, 'double');
fwrite(fid, 4, 'uint32');
fwrite(fid, 4, 'uint32');
fwrite(fid, 4, 'double');
fclose(fid);
A = sparse_array_in('sparse_binary.dat');
对于A
,我得到:
if fid < 0
A = [];
return;
end
A =
1 0 0 0 0 0 0
0 2 0 0 0 0 0
0 0 3 0 0 0 0
0 0 0 4 0 0 0
0 0 0 0 0 0 0
。。。这就是我们所期望的。我必须编写函数,然后在老师提供的评分器上提交,这个评分器会告诉你函数是否正确,但它不会说什么是错误的。我已经尝试了好几个小时,但没有效果,我希望有人能帮我找出我遗漏了什么,因为我看不到任何错误…你肯定需要创建自己的测试文件,因为你没有访问“分级器”文件的权限。从一个非常简单的开始,然后添加几个明显错误的额外代码,看看你的代码是否能够处理它们。我理解你所做的,但是评分员说它仍然不正确。我认为一个问题可能是分级器传递了文件,例如:
5741123444
,甚至可能是在列向量上。这可能是导致您的解决方案出现错误的原因吗?@Hec46-我需要知道分级机传递数据的确切方式,否则我将永远无法得到正确的结果。我假设文本文件以空格分隔,回车分隔。@Hec46-您的文章中也没有明确说明数据的格式。请更新它,以便我们确切地知道文件的结构。对不起,让我们看看我是否可以更好地解释它。在第一个任务中,我被要求编写一个函数,给定一个数组和一个文件名,然后按照我在文章中解释的结构将这个数组写到一个二进制文件中。在测试之后,我看到它在一个列向量上运行。然后,这个.dat
文件可以传递给第二个函数,它应该返回我传递给第一个函数的相同数组。老师刚刚告诉我,为了比较结果,我需要使用isequal()并得到一个1作为结果。我希望这能澄清一点,我现在就编辑这篇文章。谢谢大家!@Hec46-啊,如果它是二进制的,那么使用fread
是合理的。我还是会等到你更新你的帖子。