【问题标题】:optimize this code?优化这段代码?
【发布时间】:2012-08-23 08:02:13
【问题描述】:

我有一个名为 reference 的“父”文本文件,即:

VERSION 3.82
CALCULATION 3
OPTIONS 0
PROJNAME 
DATE 
ENGINEER 
NOTES ""
PASSWORD 
MSTART CONSTANTS
RHO 1.225
RHOW 1027
VISCOS .0000182
GRAVITY 9.81
MEND

MSTART WINDND
SPMODEL 7
NLAT 31
NVER 45
LATDIM 150
VERDIM 220
LONGLS 340.2
LATLS 0
VERTLS 0
XLV 113.4
YLV 0
ZLV 0
XLW 27.72
YLW 0
ZLW 0
LAMBDA1 0
CohScale 12
COHDEC 3
SCALE 33.6
GAMMA 3.9
YDIML 0
N2 32
YDIMS 0
K1MIN 3
LENGTH 1830
STEP .2233888
UBAR 3
SEED 12
OUTFILE None
DIAM 0
HUBHT 0
TURBHTTYPE 0
TURBBOTTOM 0
GUSTAVT 0
GUSTSPEED 0
TOLERANCE 0
DLONGMIN 0
DLONGMAX 0
Z0MIN 0
Z0MAX 0
MAXITER 14
MAXSEED 100
NFILES 1
UseWindShear 0
WVMODEL 0
MATCHFILE ''
SPACING 0
SAMPLEFREQ 0
MEANSPEED 0
ILAT 0
IVERT 0
GUSTMETHOD 0
DLONG 0
ILAT 0
IVERT 0
LONGGUST 0
LATGUST 0
VERTGUST 0
iLONGGUST 0
iLATGUST 0
iVERTGUST 0
PEAKINESS 0
MAXFRAN 0
MEND

0CONSTANTS
0WINDND

这个想法是生成一组相似的文件,只改变上述文件的4个确定的行(LENGTH,STEP,UBAR,SEED)。

目前我正在使用此代码:

clc
clear all
close all


V = [4 6 8 10 12 14 16 18 20 22 24 26 28 29];


for j = 1:6
f1 = ['D:\01_department\DLC1-2']
if exist(f1,'dir') ~= 7
    mkdir(f1);
end 
fname = [f1 '\' 's0' num2str(j)];
if exist(fname,'dir') ~= 7
    mkdir(fname);
end
 for i = 1:length(V),
filename = [fname '\' num2str(V(i)) '.$PJ'];
 fid = fopen(filename,'w');
 fprintf(fid, 'VERSION 3.82\r\n')
 fprintf(fid, 'CALCULATION 3\r\n')
 fprintf(fid, 'OPTIONS 0\r\n')
 fprintf(fid, 'PROJECTNAME\t\r\n')
 fprintf(fid, 'DATE\t\r\n')
 fprintf(fid, 'ENGINEER\t\r\n')
 fprintf(fid, 'NOTES\t""\r\n')
 fprintf(fid, 'PASSWORD\t\r\n')
 fprintf(fid, 'MSTART CONSTANTS\r\n')
 fprintf(fid, 'RHO 1.225\r\n')
 fprintf(fid, 'RHOW 1027\r\n')
 fprintf(fid, 'VISCOS 0.0000182\r\n')
 fprintf(fid, 'GRAVITY 9.81\r\n')
 fprintf(fid, 'MEND\r\n')
 fprintf(fid, '\r\n')
 fprintf(fid, 'MSTART WINDND\r\n')
 fprintf(fid, 'SPMODEL 7\r\n')
 fprintf(fid, 'NLAT 31\r\n')
 fprintf(fid, 'NVER 45\r\n')
 fprintf(fid, 'LATDIM 150\r\n')
 fprintf(fid, 'VERDIM 220\r\n')
 fprintf(fid, 'LONGLS 340.2\r\n')
 fprintf(fid, 'LATLS 0\r\n')
 fprintf(fid, 'VERTLS 0\r\n')
 fprintf(fid, 'XLV 113.4\r\n')
 fprintf(fid, 'YLV 0\r\n')
 fprintf(fid, 'ZLV 0\r\n')
 fprintf(fid, 'XLW 27.72\r\n')
 fprintf(fid, 'YLW 0\r\n')
 fprintf(fid, 'ZLW 0\r\n')
 fprintf(fid, 'LAMBDA1 0\r\n')
 fprintf(fid, 'CohScale 12\r\n')
 fprintf(fid, 'COHDEC 3\r\n')
 fprintf(fid, 'SCALE 33.6\r\n')
 fprintf(fid, 'GAMMA 3.9\r\n')
 fprintf(fid, 'YDIML 0\r\n')
 fprintf(fid, 'N2 32\r\n')
 fprintf(fid, 'YDIMS 0\r\n')
 fprintf(fid, 'K1MIN 3\r\n')
 fprintf(fid, 'LENGTH %g\r\n', V(i)*610)
 fprintf(fid, 'STEP %g\r\n', V(i)/13.4295)
 fprintf(fid, 'UBAR %g\r\n', V(i))
 fprintf(fid, 'SEED %i\r\n', randi(999,1))
 fprintf(fid, 'OUTFILE None\r\n')
 fprintf(fid, 'DIAM 0\r\n')
 fprintf(fid, 'HUBHT 0\r\n')
 fprintf(fid, 'TURBHTTYPE 0\r\n')
 fprintf(fid, 'TURBBOTTOM 0\r\n')
 fprintf(fid, 'GUSTAVT 0\r\n')
 fprintf(fid, 'GUSTSPEED 0\r\n')
 fprintf(fid, 'TOLERANCE 0\r\n')
 fprintf(fid, 'DLONGMIN 0\r\n')
 fprintf(fid, 'DLONGMAX 0\r\n')
 fprintf(fid, 'Z0MIN 0\r\n')
 fprintf(fid, 'Z0MAX 0\r\n')
 fprintf(fid, 'MAXITER 14\r\n')
 fprintf(fid, 'MAXSEED 100\r\n')
 fprintf(fid, 'NFILES 1\r\n')
 fprintf(fid, 'UseWindShear 0\r\n')
 fprintf(fid, 'WVMODEL 0\r\n')
 fprintf(fid, 'MATCHFILE %c\r\n', '')
 fprintf(fid, 'SPACING 0\r\n')
 fprintf(fid, 'SAMPLEFREQ 0\r\n')
 fprintf(fid, 'MEANSPEED 0\r\n')
 fprintf(fid, 'ILAT 0\r\n')
 fprintf(fid, 'IVERT 0\r\n')
 fprintf(fid, 'GUSTMETHOD 0\r\n')
 fprintf(fid, 'DLONG 0\r\n')
 fprintf(fid, 'ILAT 0\r\n')
 fprintf(fid, 'IVERT 0\r\n')
 fprintf(fid, 'LONGGUST 0\r\n')
 fprintf(fid, 'LATGUST 0\r\n')
 fprintf(fid, 'VERTGUST 0\r\n')
 fprintf(fid, 'iLONGGUST 0\r\n')
 fprintf(fid, 'iLATGUST 0\r\n')
 fprintf(fid, 'iVERTGUST 0\r\n')
 fprintf(fid, 'PEAKINESS 0\r\n')
 fprintf(fid, 'MAXFRAN 0\r\n')
 fprintf(fid, ' MEND\r\n')
 fprintf(fid, '\r\n')
 fprintf(fid, '0CONSTANTS\r\n')
 fprintf(fid, '0WINDND\r\n')
 fclose(fid)
 end
end

但是这样一来,代码大部分时间都花在了编写输出上。我想更多地做同样的事情,只阅读参考文件(使用 fopen() 或其他命令)和只更改(打印)

fprintf(fid, 'LENGTH %g\r\n', V(i)*610)
fprintf(fid, 'STEP %g\r\n', V(i)/13.4295)
fprintf(fid, 'UBAR %g\r\n', V(i))
fprintf(fid, 'SEED %i\r\n', randi(999,1))

在新文件中。

有人知道如何实现这个结果吗?如果可能的话,我也想矢量化而不是使用 for 循环。

否则,我在想这样的过程: 感谢您的回答并与我分享代码。

您可能已经注意到代码由块组成:它们以“MSTART”开始,以“MEND”结束;每个 MSTART 后跟单个块的标签/名称。

在这种情况下,块是 CONSTANTS 和 WINDND。我想知道是否有可能:

1.read the parent file;
2.find the different block the parent file presents;
3.store the information/strings of each block in a Matlab structure;
4.write new files just recalling the blocks of the parent file;
5.look for strings LENGTH, STEP, UBAR, SEED;
6.update the above string with the corresponding formula;
7.store in a specified folder.

代码的开头是:

%# read lines
fid = fopen('file.txt','rt');
C = textscan(fid, '%s', 'Delimiter','\r\n'); 
C = C{1};  fclose(fid);

%# start/end of each structure
startIdx = find(ismember(C, 'MSTART'));
endIdx = find(ismember(C, 'MEND'));

但是我不知道如何继续,因为我只是 Matlab 的大一新生,尤其是文本/结构操作。

希望你对我有耐心。

问候。

提前感谢大家。

最诚挚的问候, 弗朗切斯科

【问题讨论】:

  • 所以我认为这些是其他程序的配置文件。设置的顺序是否重要,或者它们可以是任何顺序?
  • 查看我的答案的编辑。这在这里有效(R2010a)。如果您有任何问题,请告诉我。
  • 为什么要在 Matlab 中执行此操作?例如在 linux 上,您可以使用 sed 等工具轻松替换部分文本文件
  • 我很困惑您的原始代码表现如此糟糕。您能否给出一些数字,该解决方案为您提高了多少性能?
  • 性能并没有很大的提升,但代码结果比每行的粗暴 fprintf 更干净、更优雅。但是对于以某种方式分布在感兴趣的文件夹中的 1440 个文件的生成,经过的时间约为 1.45 秒。

标签: matlab io fopen printf textscan


【解决方案1】:

这应该有效:

clc, clear all, close all

V = [4 6 8 10 12 14 16 18 20 22 24 26 28 29];


fid = fopen('parent.txt', 'r');
C = textscan(fid,'%s', 'delimiter', '\r\n');
C = C{1};
fclose(fid);

D = C;
for j = 1:6
    f1 = 'd:\01_department\dlc1-2';
    if exist(f1,'dir') ~= 7, mkdir(f1); end

    fname = [f1 '\' 's0' num2str(j)];
    if exist(fname,'dir') ~= 7, mkdir(fname); end

    for i = 1:numel(v)
        filename = [fname '\' num2str(V(i)) '.$pj'];

        D{strncmp('LENGTH', c, length('LENGTH'))} = ...
            sprintf('length %g', V(i)*610);

        D{strncmp('STEP', c, length('STEP'))} = ...
            sprintf('STEP %g', V(i)/13.4295);

        D{strncmp('UBAR', c, length('UBAR'))} = ...
            sprintf('UBAR %g', V(i));

        D{strncmp('SEED', c, length('SEED'))} = ...
            sprintf('SEED %i', randi(999,1));


        fid = fopen(filename,'w');        
        txt = sprintf([repmat('%s\r\n',1,size(d,1)),'\r\n'],d{:});        
        fprintf(fid, '%s', txt);        
        fclose(fid);

    end
end

这仍然可以改进——要替换的字符串是理想的矢量化,和/或只在命令中输入一次。但是哦,好吧,这应该已经给你一个显着的加速。

【讨论】:

  • 我希望文件的结构保持不变;不幸的是,目前我没有免费许可证(因为它们是浮动的),所以如果你能给我提供一段代码,我将不胜感激:) 谢谢
  • 成功了;唯一的缺陷是 repmat('%s\n',1,size(d,1)); 中缺少 \r我将其更改为 repmat('%s\r\n',1,size(d,1))。非常感谢!!!
  • @FrancescoPerrone 是的,我来自\n 表示换行符(Linux)的土地,\r\n 是与其他人交流时容易忘记的麻烦world (MS Windows) :) 无论如何,很高兴它现在可以正常工作了。
  • 主要的一点是,这些文件要以准确的格式生成,以便提供工具来详细说明它们。所以 \r\n 是至关重要的 :) 再次感谢您的支持
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
相关资源
最近更新 更多