Matlab在矢量化代码中调整

时间:2013-08-29 15:45:22

标签: matlab concatenation vectorization

几天前,我发布了this question,并得到了以下出色的解决方案:

fid = fopen('C:\Testes_veloc\test.txt', 'Wt');
fmt = sprintf('%s;%d;%%d;%d;%d;%%d;%%d;%%d;%%.4f \\n',str1,num1,0,2)
[a,b,c,d] = ndgrid(vect2,vect1,day,1:15);
out = sprintf(fmt, [d(:), c(:), b(:), a(:), reshape(permute(MD,[2,1,3,4]),[],1)]'); 
fprintf(fid, '%s', out);

变量str1num1dayvect1vect2MD是此函数的输入:

  • str1是一个字符串1x1
  • num1是整数1x1
  • day是向量10x1
  • vect1是向量7x1
  • vect2是向量180x1
  • MD是4D矩阵(7x180x10x15)

目标是提供如下文本文件:

result.txt:
RED;12;7;0;2;1;4;7;0.0140
RED;12;7;0;2;2;9;7;0.1484
RED;12;7;0;2;3;7;4;0.1787
RED;12;7;0;2;4;2;6;0.7891
RED;12;7;0;2;5;9;6;0.1160
RED;12;7;0;2;6;9;1;0.9893

但是,str1不是1x1字符串;它是一个名字的矢量(189000x1),它具有我想要的文本的长度。换句话说,我有许多不同的字符串,而不仅仅是'RED'。是否可以将此矢量化循环调整为这种情况?

我尝试了这个(将str1(:)添加到连接部分),但没有成功:

fmt = sprintf('%%s;%s;%d;%%d;%d;%d;%%d;%%d;%%d;%%.4f \\n',str1,num1,0,2)
out = sprintf(fmt, [str1 (:), d(:), c(:), b(:), a(:), reshape(permute(MD,[2,1,3,4]),[],1)]'); 

例如,str(1,:) = 'RED'; str(2,:) = 'FHAW'; str(3,:) = 'KI81';像这样的细胞。 它无法将字符串连接到数字。有没有人有解决方案?

提前致谢。

1 个答案:

答案 0 :(得分:1)

sprintf(与fprintf一样)使用提供的顺序使用参数填充格式字段。如果提供的参数多于格式调用的参数,则这些函数将使用其他函数重复格式:

sprintf('%s %i\n', 'a', 1, 'b', 2, 'c', 3)

% returns

ans =

a 1
b 2
c 3

使用Matlab的单元格解开技术,您可以先准备好参数,然后将它们传递给sprintf:

tmp = {'a', 1, 'b', 2, 'c', 3};
sprintf('%s %i\n', tmp{:})

通过连接单元格数组可以获得更高的效果:

tmp1 = {'a','b','c'};
tmp2 = [1 2 3];
tmp = [tmp1' num2cell(tmp2')]'
sprintf('%s %i\n', tmp{:})

% Returns

tmp = 

    'a'    'b'    'c'
    [1]    [2]    [3]


ans =

a 1
b 2
c 3

请注意, tmp 的布局会以格式转换为布局。这是因为Matlab以行主顺序读取数据,因此它将向下行,然后向下行,以获取sprintf的参数。

因此,在您的场景中,您需要使用您的参数创建一个大型单元格数组,然后将其传递给sprintf。

fid = fopen('C:\Testes_veloc\test.txt', 'Wt');
fmt = sprintf('%%s;%d;%%d;%d;%d;%%d;%%d;%%d;%%.4f \\n',num1,0,2)
[a,b,c,d] = ndgrid(vect2,vect1,day,1:15);
tmp = [str(:) num2cell([d(:) c(:) b(:) a(:) reshape(permute(MD,[2,1,3,4]),[],1)]'])]';
fprintf(fid, fmt, tmp{:});
fclose(fid);