sprintf confusion (Matlab) - matlab

Quick question,
I would like to make a count from 50-70 using sprintf in Matlab. This example prints 0101-0120
for i = 1:20
filename = sprintf('Brain_01%02d.dcm', i);
[X(:,:,1,i), amap] = dicomread(filename);
end
How would I change this to print 0151-0170?

The answer seemed obvious at first, but it seems like another issue might be related to the indexing of X getting broken if i doesn't start at one. Here's one way to address that while handling pre-allocation of X,
imgInds = 151:170;
di = dicominfo(sprintf('Brain_%04d.dcm',imgInds(1)));
X = zeros(di.Height,di.Width,1,numel(imgInds),class(dicomread(di))); % modify
for i = 1:numel(imgInds),
filename = sprintf('Brain_%04d.dcm', imgInds(i));
[X(:,:,1,i), amap] = dicomread(filename);
end
For clarity, I think it is better to build your sprintf with %04d instead of 01%02d. You should set the size of X accordingly on the line labeled modify, particularly the third dimension since I assume your actual code will not have this be 1.

I'm guessing this should do it:
for i = 51:70
filename = sprintf('Brain_01%02d.dcm', i);
[X(:,:,1,i), amap] = dicomread(filename);
end

Thank you for your responses! Actually all I needed to do (for my purposes) was:
for i = 1:20
filename = sprintf('Brain_01%02d.dcm', i + 49);
[X(:,:,1,i), amap] = dicomread(filename);
end
which made the count start from 50.

Related

Generate a heterokskedastic series in MATLAB?

I am trying to generate a heteroskedastic error term in MATLAB.
I have found a good link to help here, the problem I am having is replicating this in MATLAB.
Here is my attempt:
n = [(1:100) (1:100)]';
sigma2 = n.^(1.3);
t = size(n,1);
for i = 1:200
eps(i) = normrnd(0, sqrt(sigma2(1)));
end
eps = eps'
h = archtest(eps)
However, the test for hetero indicates I still do not have heteroskedastic data, can anyone see where I am going wrong.
Looks like you're keeping sigma2 fixed in the first value inside the loop.
Replace
eps(i) = normrnd(0, sqrt(sigma2(1)));
with
eps(i) = normrnd(0, sqrt(sigma2(i)));

Why does matlab warn to preallocate a variable which is getting reset every loop?

There is a cell variable in my program which Matlab warns to preallocate it. The simple form of code is sth like this:
for i = 1:2
a = [];
a = [a,{'abc'}];
end
First I want to know why a should be preallocated, since it's getting reset in each loop. Second I don't know how to preallocate it. When I try to do so, Matlab gives me another warning, saying "The variable appears to be preallocated, but preallocation is not recommended here".
I use this code before the loop:
a = cell(1,2);
To be more specific:
for i = 1:2
a = [];
if condition1
a = {'abc'};
end
if condition2
a = [a,{'def'}];
end
b = [{'string'},a];
end
I want b to be a 1x1 cell array if the conditions are not true, so I need to reset a to an empty var in each loop.
Update:
I found a way, hinted by Lee's answer, but still doesn't know why. Using a = [a(:),{'def'}]; instead of a = [a,{'def'}]; solved the warning.
You made a a new variable, thus the former a = cell(1,2) was never used, which made matlab raised the warning.
You can use sth like
a = cell(1,2);
for ii = 1:2
a{ii} = 'abc';
end
or if you really want to change the size of a,
for ii = 1:2
a = {'a1'};
a = [a(:); {'abc'}];
end

Looping a process, outputting numerically labelled variables each time

I have about 50 different arrays and I want to perform the following operation on all of them:
data1(isnan(data1)) = 0;
coldata1 = nonzeros(data1);
avgdata1 = mean(coldata1);
and so on for data2, data3 etc... the goal being to turn data1 into a vector without NaNs and then take a mean, saving the vector and the mean into coldata1 and avgdata1.
I'm looking for a way to automate this for all 50, rather than copy it 50 times and change the numbers... any ideas? I've been playing with eval but no luck so far. Also tried:
for y = 1:50
data(y)(isnan(data(y))) = 0;
coldata(y) = nonzeros(data(y));
avgdata(y) = mean(coldata(y));
end
You can do it with eval but really should not. Rather use a cell array as suggested here: Create variables with names from strings
i.e.
for y = 1:50
data{y}(isnan(data{y})) = 0;
coldata{y} = nonzeros(data{y});
avgdata{y} = mean(coldata{y});
end
Also read How can I create variables A1, A2,...,A10 in a loop? for alternative options.

Parse text file into structure

For some purposes, I wanna give an external text file as input of one of my MATLAB functions.
Generally this text file shows the following layout:
-----------------------------------------------------
HubHt = 90;
GridWidth = 220;
GridHeight = 220;
Ny = 35;
Nz = 37;
Nfft = 8192;
time = 620;
Uhub = 15;
Coherence = Bladed;
-----------------------------------------------------
To read it in, I'm currently calling this piece of code:
fid = fopen('test.inp','r+');
A = textscan(fid,'%s','Delimiter',';','commentStyle', '-','CollectOutput',1);
fclose(fid);
A = A{1};
inputs = regexp(A,' = ','split');
The last variable, inputs results in a <9x1> cell; each element will be a <1x2> cell.
The first element of the <1x2> cell is supposed to be the field of a overall INPUT structure, whereas the second element is the associated parameter.
At the moment, I'm using a quite static and awful way to achieve my goal:
inp = struct(char(inputs{1}(1)),str2double(inputs{1}(2)),char(inputs{2}(1)),str2double(inputs{2}(2)),char(inputs{3}(1)),str2double(inputs{3}(2)),char(inputs{4}(1)),str2double(inputs{4}(2)),char(inputs{5}(1)),str2double(inputs{5}(2)),char(inputs{6}(1)),str2double(inputs{6}(2)),char(inputs{7}(1)),str2double(inputs{7}(2)),char(inputs{8}(1)),str2double(inputs{8}(2)),char(inputs{9}(1)),char(inputs{9}(2)));
I believe that exist quite better ways to do the same: I'd like if you could share one with me.
You can use cell2struct:
% create cell vector where fieldnames and values alternate
tmp = [inputs{:}];
inp = cell2struct(tmp(2:2:end), tmp (1:2:end), 2);
Since what you have written is (nearly) valid Matlab source code why not give it the file extension .m and just run it ? Or call it from inside your function.
This is is an approach which we've used a lot; it's straightforward and simple. Obviously you have to make sure that it is (entirely) valid Matlab source but that's not difficult.

Problem with a variable not changing value in MATLAB

So I have one problem with my code, which is that one variable is not working as it's supposed to do. Here are the codes I'm using:
format long
f = inline('-x.^2');
for i = 0:10
[I(i+1) h(i+1) tid(i+1)] = trapets(f,0,1,2^i);
end
for i = 0:10
trunk(i+1) = I(i+1) - log(2);
end
hold on
grid on
plot(log(h),log(trunk),'r+')
t = -7:0;
c = polyfit(log(h),log(trunk),1);
yy = polyval(c,t);
plot(t,yy)
grid off
hold off
koefficienter = real(c)
and also this:
function [ I,h,tid ] = trapets(f,a,b,n )
h=(b-a)/n;
tic;
I=(f(a)+f(b));
for k=2:2:n-2
I = I+2*f(a+k*h);
end
for k = 1:2:n-1
I = I + 4*f(a+k*h);
end
I = I * h/3;
tid = toc;
end
So the problem here is that the variable I is not changing value. It gets 11 values when I run the first code (I don't run the last code I wrote, it's only used by the first one), but the values are all the same. I don't know if the problem is that the variable n, which I use in the the second code, never change value, although I'm trying to do that with the "2^i" part in "trapets(f,0,1,2^i)". If the case is that n never change value, is there a solution to do that?
And if the problem is not the variable n, why doesn't the variable I change value in the code?
After running your program I found out the I always equals -1/h after the for loops, which makes I = I * h/3; always give you the same result.