Matlab fprintf в цикле неожиданное поведение

#matlab #for-loop #printf

#matlab #для цикла #printf

Вопрос:

Я многократно выполняю вычисления с разными значениями во вложенных циклах for с текущими уровнями 7. Результаты моих вычислений должны быть записаны в файл. Поэтому я использую 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: %dn', 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
 

Когда я запускаю это и открываю сгенерированный файл, я получаю правильный результат для первой строки первой итерации, но уже 2-я строка и все последующие являются странными:

 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. Вы установили точку останова в своей fprintf строке, чтобы проверить, правильно ли вычисляются ваши переменные после первой итерации?

Ответ №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: %dn', thresalg, thressig, 
    func2str(diffalg), detectsig, arrwindowsize(windowsizei), 
    arrwindowshape{windowshapei}, K,int32(fp),int32(fn),int32(tp),int32(tn)));
 

Обратите внимание, что K это записывается в строку в виде числа с плавающей запятой в конце первой строки. Если K это массив, это может объяснить, почему FP , FN , TP и TN записываются как числа с плавающей запятой, а не как целые числа (согласно %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: %dn', thresalg, thressig, 
    func2str(diffalg), detectsig, arrwindowsize(windowsizei), 
    arrwindowshape{windowshapei}, K,int32(fp),int32(fn),int32(tp),int32(tn));
 

as fprintf принимает те же входные sprintf данные, что и (строка формата и переменный список аргументов) после идентификатора файла ( logfile ).