How do I make a plot in Matlab if I do not know the specific size of the array? - arrays

I have some code
function runTubulin()
n = 10;
for j = 1:n
TubulinModel();
end
plot(TubulinModel(), n);
So my problem is that TubulinModel has a random number of outputs So I keep getting
??? Error using ==> TubulinModel Too
many output arguments.
Error in ==> runTubulin at 11
plot(TubulinModel(), n);
Is there A way to plot the data when I do not know the size of the array?

The error you are getting (Too many output arguments) implies that the function TubulinModel doesn't actually return any outputs. The function TubulinModel is expected to pass at least one output argument for the PLOT command to use, which it doesn't appear to be doing. You can check this by trying the following:
a = TubulinModel(); %# Place the output in a variable instead
If this gives you an error, then it means you will have to modify TubulinModel so that it returns the data you need, or places that data in a global variable that you can access outside of the function and use for the plot.

Your loop doesn't appear to do anything different with the TublinModel function on subsequent iterations. Also, the plot function calls the function again, the same way the loops did. Assuming different data of random lengths is returned by each loop, you can store each set of data in an object array, then find out what parameters to use before plotting.
function runTubulin()
n = 10;
max_length = 0; max_pos = 0; max_neg = 0;
for j = 1:n
data{j} = TublinModel(); % get your data, then characterize it
if max(data(j)) > max_pos, max_pos = max(data(j)); end
if max(-data(j)) > max_neg, max_neg = max(-data(j)); end
end
figure(1); % new axes
axis([0 10 -max_neg max_pos]); hold on; % scale the axis and freeze it
for j = 1:n
plot(length(data(j)),data(j));
end
Hope that helps!

When you call plot with two parameters, the first will be the x-axis data, and the second the y-axis data. Is this what you intend? If you want TubulinModel() to be the y-axis data, you can do plot(TubulinModel()). See help plot for more information.
I don't understand why you call TubulinModel() ten times in the loop before calling it an eleventh time in plot?

Related

Calculate the mean of an array in MATLAB

I have an array in Matlab "Numbers" that is stored in the workspace as a 400x1 double. I know how to calculate the mean of this data, but the problem I have is actually writing the code to do this. I know there are functions built-in which I could use, but I want to try and calculate this using only low-level IO commands and I'm not sure how to go about doing this. I was thinking the correct way to do this would be to create a for loop and a variable containing the total that adds each element in the array until it reaches the end of the array. With that, I could simply divide the variable 'Total' by the number of elements '400' to get the mean. The main problem I have is not knowing how to get a for loop to search through each element of my array, any help in figuring that part out is much appreciated. Thank you.
mean(Numbers) will do it for you. If not,
sum(Numbers)/length(Numbers)
or, if you insist on not using built-in functions,
sums = 0;
counter = 0;
for val = Numbers
sums = sums + val;
counter = counter + 1;
end
Numbers_mean = sums/counter;
although this will almost always be slower than just calling mean.

Looping through a set of sequences satisfying a certain property, without storing them

Below is a MATLAB code (recursion) which inputs a vector (l_1,l_2,...,l_r) of non negative integers and an integer m prints all sequences (m_1,m_2,...,m_r) satisfying:
0 <= m_i <= l_i for all 1 <= i <= r and m_1 + m_2 + ... + m_r = m
The r is captured in the function definition by calling the size of the (l_i) array below:
function arr=sumseq(m,lims)
arr=[];
r=size(lims,2);
if r==0 || m<0
arr=[];
elseif r==1 && lims(1)>=m
arr=[m]; %#ok<NBRAK>
else
for i=0:lims(1)
if(lims(1)<0)
arr=[];
else
v=sumseq(m-i,lims(2:end));
arr=[arr;[i*ones(size(v,1),1) v]];
end
end
end
end
Here what I have done is, stored a whole array of them and made it my output. Instead I want to only print them one by one and not store them in an array. This seems simple enough as there is not much choice in which line(s) I need to change (I believe it is the contents of the else block inside the for loop), but I get into a fix every time I try to achieve it.
(Also, MATLAB warned me that if I kept re-initializing the array with a larger array like in the statement:
arr=[arr;[i*ones(size(v,1),1) v]];
it reallocates a fresh array for all the contents of arr and spends a 'lot' of time doing so.)
In short: recursion or not, I want to save the trouble of storing it, and need an algorithm which is as efficient as or more efficient than what I have here.

Calculating sum of array elements and reiterate for entire array in MATLAB

I have a vector A of size 7812x1 and would like to calculate the sum of fixed windows of length 21 (so 372 blocks). This should be reiterated, so that the output should return a vector of size 372x1.
I have t=7812, p=372, w=21;
for t=1:p
out = sum(A((t*w-w+1):(t*w)));
end
This code, however, does not work. My idea is that the part ((t*w-w+1):(t*w)) allows for something like a rolling window. The window is of length 21, so there is not really a need to express is with variables, yet I think it keeps some flexibility.
I've seen potentially related questions (such a partial sum of a vector), yet I'm not sure whether this would result the output desired.
Reshape into a matrix so that each block of A is a column, and compute the sum of each colum:
result = sum(reshape(A, w, []), 1);
Following your idea of using a rolling/moving window (requires Matlab 2016a or later):
t = 7812; w = 21; % your parameters
A = rand(t,1); % generate some test data
B = movsum(A,w); % the sum of a moving window with width w
out = B(ceil(w/2):w:end); % get every w'th element

Compute mean value over a sliding window in MATLAB

I have a time series data or considering a real valued data of length N. I want to create sub-blocks of length k, which is the window length. The value of k can be arbitrarily chosen. This creates problem since the window size is the same across the data. I want to store each subblock in an array. But I am stuck in creating sub-blocks of the data and to include a check so that the (mod(N, nseg)) nseg must be divisible by the data length.
N = 512; %length of the time series
data = rand(N,1);
window_length = 30; %k
Nseg = floor(N/window_length) %Number of segments or blocks
Modified_Data = [mean(reshape(data,window_length,Nseg))]; %Throws error
If you have the Image Processing toolbox you could use im2col to slide a specific block size over the entire time series. Each column of the output represents the data from one of those blocks.
values = im2col(data, [window_length 1], 'distinct');
Since it looks like you just want the mean over each block, you could also use blockproc to do this.
means = blockproc(data, [window_length, 1], #(x)mean(x.data));
If you do not have the Image Processing Toolbox, you can instead use accumarray to perform this task.
means = accumarray(floor((0:(N-1)).'/window_length) + 1, data, [], #mean);
If you want to discard any data that extends beyond a number which is divisible by window_length, you can do this with something like the following:
data = data(1:(numel(data) - mod(numel(data), window_length)));
If you want overlapping data, you'll either want to use straight-up convolution (the preferred method)
means = conv(data(:), ones(5, 1)/5, 'same');
Or you can create overlapping blocks with im2col by omitting the last input.
values = im2col(data, [window_length 1]);
means = mean(values 1);
If you have R2016a+, consider using the built-in movmean function:
N = 512; %length of the time series
data = rand(N,1);
window_length = 30; %k
Modified_Data = movmean(data, window_length);
See the documentation for further details and other options.
If I understand your question correctly, it's pretty straightforward:
filter(ones(N,1)/N,1,signal)
If you think about it filtering with [1/N 1/N 1/N...1/N] is exactly calculating the localized mean...

Summing blocks of numbers in a vector in matlab

I need to sum consecutive 96 value blocks in a vector of n (in one case 14112) values. The background is that the values are 15-min temperature measurements and I want to average 96 at a time (1 to 96, 96+1 to 2*96 ... n*96+1 to (n+1)*96) to produce a daily average. This could of course be done in a loop stepping 96 but my question is if there is a more efficient way to accomplish this in Matlab.
By using reshape and mean:
data = randn(1,14112); % example data. Row vector
m = 96; % block size. It is assumed that m divides length(data)
result = mean(reshape(data,m,[]));
As #Dan points out, if the number of elements is not a multiple of the block size some padding is necessary. The following code, due to him, does the necessary padding in the last block while keeping the mean of that block. Thanks also to #DennisJaheruddin for his sugggestion not to modifiy original variable:
data = randn(1,14100); % example data. Row vector
m = 96; % block size
n = length(data);
result = mean(reshape([data repmat(mean(data(n-mod(n,m)+1:n)), 1, m - mod(n, m))], m, []));
Here is an alternate way to nicely deal with the problem, it also works if the lenght of the data is not a nice multiple of the window size:
data = randn(1,14112);
w = 96;
N = numel(data);
M = NaN(w,ceil(N/w));
M(1:N) = data;
nanmean(M)
If you don't want to include partial days at the end, use fix instead of ceil.

Resources