Matlab fprintf在循环中出现意外行为

时间:2014-06-26 13:02:27

标签: matlab for-loop printf

我使用当前7个级别的嵌套for循环中的不同值重复执行计算。我的计算结果应记录到一个文件中。因此,我使用fprintf。以下是我的代码摘录:

loadsignals;
fprintf('\n');
logfile = fopen(logfilename,'w');
if (logfile == -1)
    error('Couldn''t open logfile!');
end

%%% Initialisation of variables %%%
for thresalgi=1:length(arrthresalg)
for thressigi=1:length(arrthressig)
    for diffalgi=1:length(arrdiffalg)
        for detectsigi=1:length(arrdetectsig)
            for windowsizei=1:length(arrwindowsize)
                for windowshapei=1:length(arrwindowshape)
                    for Ki=1:length(arrK)
                        %% Prepare this round
                        thresalg  = arrthresalg{thresalgi};
                        thressig  = arrthressig{thressigi};
                        diffalg   = arrdiffalg{diffalgi};
                        detectsig = arrdetectsig{detectsigi};
                        K = arrK;
                        if strcmpi(arrwindowshape{windowshapei},'rectangle')
                            window = ones(1,arrwindowsize(windowsizei));
                        end
                        if strcmpi(arrwindowshape{windowshapei},'saw')
                            window = (1:arrwindowsize(windowsizei))/arrwindowsize(windowsizei);
                        end
                        if strcmpi(arrwindowshape{windowshapei},'sraw')
                            window = (arrwindowsize(windowsizei):-1:1)/arrwindowsize(windowsizei);
                        end
                        if strcmpi(arrwindowshape{windowshapei},'exponential')
                            window = flip(exp(1:arrwindowsize(windowsizei))/exp(arrwindowsize(windowsizei)));
                        end
                        if strcmpi(arrwindowshape{windowshapei},'rexponential')
                            window = exp(1:arrwindowsize(windowsizei))/exp(arrwindowsize(windowsizei));
                        end
                        if strcmpi(arrwindowshape{windowshapei},'root')
                            window = flip(sqrt((1:arrwindowsize(windowsizei))/arrwindowsize(windowsizei)));
                        end
                        if strcmpi(arrwindowshape{windowshapei},'rroot')
                            window = sqrt((1:arrwindowsize(windowsizei))/arrwindowsize(windowsizei));
                        end
                        %% Detect events
                        detectEvents; % Remark: the variables top of this statement are changed in this script, may this cause issues?
                        %% Evaluate result
                        [fp,fn,tp,tn] = compareResults(solevts,y,tolerance);
                        results{thresalgi,thressigi,diffalgi,detectsigi,windowsizei,windowshapei,Ki} = {fp, fn, tp, fn};
                        fprintf(logfile,sprintf('Thresalg: %s Thressig: %s Diffalg: %s Detectsig: %s Winsize: %d Winshape: %s K: %f done.\n     FP: %d FN: %d TP: %d TN: %d\n', thresalg, thressig, func2str(diffalg), detectsig, arrwindowsize(windowsizei), arrwindowshape{windowshapei}, K,int32(fp),int32(fn),int32(tp),int32(tn)));
                    end
                end
            end
        end
    end
end
end

当我让它运行并打开生成的文件时,我得到了第一次迭代的第一行的正确结果,但已经是第二行以及所有后续内容都很奇怪:

Thresalg: meanval Thressig: d Diffalg: @(x)fwpdiff(x) Detectsig: s Winsize: 2 Winshape: rectangle K: 0.100000 done.
     FP: 1.246905e-01 FN: 1.554772e-01 TP: 1.938653e-01 TN: 2.417315e-01
Thresalg: 3.014163e-01 Thressig: 3.758374e-01 Diffalg: 4.686335e-01 Detectsig: 5.843414e-01 Winsize: 7.286182e-01 Winshape: 9.085176e-01 K: 1.132835 done.
     FP: 1.412538e+00 FN: 1.761300e+00 TP: 2.196174e+00 TN: 2.738420e+00

对我来说,似乎只有传递给fprintf的指针在数据写入缓冲区时不再有效。那可能吗?

我试图找到一个更简单的例子来重现这个问题,但是无法创建一个。

有没有人发现类似的东西?或者我的代码中是否存在(微不足道的)错误?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我想知道问题是否与变量K有关?最里面的for循环是

for Ki=1:length(arrK)

以后,在这个循环体内,我们设置

K = arrK;

所以现在一个局部变量被设置为可能有一个或多个数字的数组。 fprintf

fprintf(logfile,sprintf('Thresalg: %s Thressig: %s Diffalg: %s Detectsig: %s Winsize: %d 
    Winshape: %s K: %f done.\n     FP: %d FN: %d TP: %d TN: %d\n', thresalg, thressig, 
    func2str(diffalg), detectsig, arrwindowsize(windowsizei), 
    arrwindowshape{windowshapei}, K,int32(fp),int32(fn),int32(tp),int32(tn)));

请注意,K正在第一行末尾以浮点形式写入字符串。如果K是一个数组,这可以解释为什么FPFNTPTN被写为浮点而不是整数(按照%d)。我认为代码应该K而不是Ki作为整数。

尝试进行更改,看看会发生什么!

另请注意,您无需使用sprintf来创建传递给fprintf的字符串。你可以改为

fprintf(logfile,'Thresalg: %s Thressig: %s Diffalg: %s Detectsig: %s Winsize: %d 
    Winshape: %s K: %f done.\n     FP: %d FN: %d TP: %d TN: %d\n', thresalg, thressig, 
    func2str(diffalg), detectsig, arrwindowsize(windowsizei), 
    arrwindowshape{windowshapei}, K,int32(fp),int32(fn),int32(tp),int32(tn));

因为fprintf在文件标识符(sprintf)之后与logfile(格式字符串和参数的变量列表)采用相同的输入。