How can I change input of function from file to cell array?

Hi,
I have this function dfaedit_2('filename.csv',0,0,0) and it only takes files as input. I have a cell array with a size of 19x21.
I would like to change the input into a cell array.
When I run it however I get an error:
Error using cumsum
Invalid data type. First input argument must be numeric or logical.
Error in dfaedit (line 44)
Sum = cumsum(x);
Help is much appreciated!

 Accepted Answer

Either delete or comment out lines below and change input to data. Verify cell2mat(of your cell array) gives what is expected. Or provide a sample of your input cell array and previous data file.
data=yourCellarray;
H=dfaedit(data,1,1,1);%call function
function [H]=dfaedit(data,plot_flag, outfile_flag, out_command_flag)
format short g
%x = file_name;
%fid = fopen(file_name);
%data = textscan(fid,'%f');
%fid = fclose(fid);
x = cell2mat(data);

7 Comments

thanks for the quick response! When I call the function
H=dfaedit_2(p_windows,1,1,1)
I get the error:
Error using cumsum
Invalid data type. First input argument must be numeric or logical.
Error in dfaedit (line 44)
Sum = cumsum(x);
When I run
x = cell2mat(data)
I get the error:
Error using cat
Dimensions of arrays being concatenated are not consistent.
Error in cell2mat (line 78)
m = cat(1,m{:});
So does that mean I cant use cell2mat?
Thanks for the help!
function [H]=dfaedit(data,plot_flag, out_command_flag)
format short g
x = data{1};
numberpoints = length(x);
MinBox = 4; % minbox #of points in a box
MaxBox = .25*numberpoints; % maxbox set 1/4 the data length
BoxSizeDensity = 4;
LogScaleFactor = power(2.0, 1.0/BoxSizeDensity);
index = 1:numberpoints;
index = reshape(index, length(index), 1); %change row to column vector
% Preliminary calculations
Sum = cumsum(x);
SumOfSumsSquared = cumsum(Sum.*Sum);
SumOfSums = cumsum(Sum);
SSc = cumsum(index.*Sum);
% now find best fit lines and find fluctuation about the line
% loop for each box size, from MinBox to MaxBox
iteration = 1;
BoxSize = MinBox;
TempBoxSize = MinBox;
while BoxSize <= MaxBox
s = 0.0;
r1 = 1./(BoxSize + 1.0);
Det = 12.0*r1*r1*r1/(1.0 - r1*r1);
vv = BoxSize*(2.0*BoxSize + 1.0)/6.0;
for j = 2:numberpoints - BoxSize
dhh = SumOfSumsSquared(j + BoxSize) - SumOfSumsSquared(j-1);
dhu = SumOfSums(j + BoxSize) - SumOfSums(j-1);
dhv = SSc(j + BoxSize) - SSc(j-1) - dhu*j;
s = s + dhh - (dhv*dhv +dhu*dhu*vv - dhv*dhu*BoxSize)*Det;
j = j + 1;
end
den = (numberpoints - BoxSize)*(BoxSize + 1.0);
Fluctuation = sqrt(s/den);
log_points_in_box(iteration,1) = log10(BoxSize);
log_Q(iteration,1) = log10(Fluctuation);
show_results(iteration,:) = [ iteration BoxSize Fluctuation log_points_in_box(iteration,1) log_Q(iteration,1) ];
iteration = iteration + 1;
% update the box size
TempBoxSize = TempBoxSize*LogScaleFactor;
while round(TempBoxSize) < BoxSize + 1.0
TempBoxSize = TempBoxSize*LogScaleFactor;
end
BoxSize = round(TempBoxSize);
end
% got all boxes; now calculate H via trendline
r_trend = corrcoef(log_points_in_box, log_Q);
coefs = polyfit(log_points_in_box, log_Q,1);
r_line = polyval(coefs,log_points_in_box);
% calculate dimension and Hurst
H = coefs(1);
D = 2-H;
%display results in command window
if out_command_flag == 1
disp(' iteration points Q Log10(pnts) Log10(Q)')
disp(show_results)
end
% display results in a figure
if plot_flag == 1
figure
h = axes('Position', [0 0 1 1], 'Visible', 'off');
axes('Position',[.1 .2 .75 .75])
plot(log_points_in_box, log_Q,'b+')
hold on
plot(log_points_in_box,r_line, 'k')
ylabel('log10(Q)');
xlabel('log10(Points in Subset)')
set(gcf, 'CurrentAxes', h);
str(1) = {[sprintf('%2.5f',coefs(1)),'x + ', sprintf('%2.5f',coefs(2)), ' = y, r^2 = ', sprintf('%2.2f',r_trend(1,2)^2), ', n = ', sprintf('%d',length(log_Q)) ]};
text(.1, .02, str, 'FontSize', 10, 'Color', 'r');
str(1) = {['H = ', sprintf('%2.3f',H) ' D = ', sprintf('%2.3f',D) ]};
text(.5, .02, str, 'FontSize', 10, 'Color', 'r');
end
end
Call function
h=dfaedit(p_windows11,1,1);
thanks this worked. Very grateful for your answer.
I was wondering however, how do I get an result (h) for every column in each of the cells. I was hoping to output a cell array with an h for each column. Apologies if I didnt mention that at the top when asking the question. Could you help me with this?
I tried using cellfun by calling the function like this:
wrapper = @(x)dfaedit(p_windows11,0,0);
h= cellfun(wrapper, p_windows, 'UniformOutput',false);
But this only yields an 19x21 cell array where each cell is the same result (see attachment).
Not sure if you saw this line:
x = data{1};
I ran out of time and quickly put out my response. In order to find the h values for all parts of the cell array, you will need to change that line to cycle through the whole cell array.
for k=1:numel(data)
x=data{k};
% put the rest of the code in here
end
Like:
function [H]=dfaedit(data,plot_flag, out_command_flag)
format short g
for k=1:numel(data)
x = data{k};
numberpoints = length(x);
MinBox = 4; % minbox #of points in a box
MaxBox = .25*numberpoints; % maxbox set 1/4 the data length
BoxSizeDensity = 4;
LogScaleFactor = power(2.0, 1.0/BoxSizeDensity);
index = 1:numberpoints;
index = reshape(index, length(index), 1); %change row to column vector
% Preliminary calculations
Sum = cumsum(x);
SumOfSumsSquared = cumsum(Sum.*Sum);
SumOfSums = cumsum(Sum);
SSc = cumsum(index.*Sum);
% now find best fit lines and find fluctuation about the line
% loop for each box size, from MinBox to MaxBox
iteration = 1;
BoxSize = MinBox;
TempBoxSize = MinBox;
while BoxSize <= MaxBox
s = 0.0;
r1 = 1./(BoxSize + 1.0);
Det = 12.0*r1*r1*r1/(1.0 - r1*r1);
vv = BoxSize*(2.0*BoxSize + 1.0)/6.0;
for j = 2:numberpoints - BoxSize
dhh = SumOfSumsSquared(j + BoxSize) - SumOfSumsSquared(j-1);
dhu = SumOfSums(j + BoxSize) - SumOfSums(j-1);
dhv = SSc(j + BoxSize) - SSc(j-1) - dhu*j;
s = s + dhh - (dhv*dhv +dhu*dhu*vv - dhv*dhu*BoxSize)*Det;
j = j + 1;
end
den = (numberpoints - BoxSize)*(BoxSize + 1.0);
Fluctuation = sqrt(s/den);
log_points_in_box(iteration,1) = log10(BoxSize);
log_Q(iteration,1) = log10(Fluctuation);
show_results(iteration,:) = [ iteration BoxSize Fluctuation log_points_in_box(iteration,1) log_Q(iteration,1) ];
iteration = iteration + 1;
% update the box size
TempBoxSize = TempBoxSize*LogScaleFactor;
while round(TempBoxSize) < BoxSize + 1.0
TempBoxSize = TempBoxSize*LogScaleFactor;
end
BoxSize = round(TempBoxSize);
end
% got all boxes; now calculate H via trendline
r_trend = corrcoef(log_points_in_box, log_Q);
coefs = polyfit(log_points_in_box, log_Q,1);
r_line = polyval(coefs,log_points_in_box);
% calculate dimension and Hurst
H(k) = coefs(1);
D = 2-H(k);
%display results in command window
if out_command_flag == 1
disp(' iteration points Q Log10(pnts) Log10(Q)')
disp(show_results)
end
% display results in a figure
if plot_flag == 1
figure
h = axes('Position', [0 0 1 1], 'Visible', 'off');
axes('Position',[.1 .2 .75 .75])
plot(log_points_in_box, log_Q,'b+')
hold on
plot(log_points_in_box,r_line, 'k')
ylabel('log10(Q)');
xlabel('log10(Points in Subset)')
set(gcf, 'CurrentAxes', h);
str(1) = {[sprintf('%2.5f',coefs(1)),'x + ', sprintf('%2.5f',coefs(2)), ' = y, r^2 = ', sprintf('%2.2f',r_trend(1,2)^2), ', n = ', sprintf('%d',length(log_Q)) ]};
text(.1, .02, str, 'FontSize', 10, 'Color', 'r');
str(1) = {['H = ', sprintf('%2.3f',H(k)) ' D = ', sprintf('%2.3f',D) ]};
text(.5, .02, str, 'FontSize', 10, 'Color', 'r');
end
end
end
sorry again for not explaining this correctly. When I run the code I get a result for each cell. However what I was looking for is a result for each column of each matrix within each cell.
For example, the first cell in p_windows11 has a size of 512x47. Therefor, I would need an output where the first cell in the new cell array (h) contains a matrix with 47 columns (1x47) or 47 results respectively.
I hope this is more clear. Again, support is very much appreciated!
function [H]=dfaedit(data)
format short g
for k=1:numel(data)
y = data{k};
h=[];
for kk=1:size(y,2)
x=y(:,kk);
numberpoints = length(x);
MinBox = 4; % minbox #of points in a box
MaxBox = .25*numberpoints; % maxbox set 1/4 the data length
BoxSizeDensity = 4;
LogScaleFactor = power(2.0, 1.0/BoxSizeDensity);
index = 1:numberpoints;
index = reshape(index, length(index), 1); %change row to column vector
% Preliminary calculations
Sum = cumsum(x);
SumOfSumsSquared = cumsum(Sum.*Sum);
SumOfSums = cumsum(Sum);
SSc = cumsum(index.*Sum);
% now find best fit lines and find fluctuation about the line
% loop for each box size, from MinBox to MaxBox
iteration = 1;
BoxSize = MinBox;
TempBoxSize = MinBox;
while BoxSize <= MaxBox
s = 0.0;
r1 = 1./(BoxSize + 1.0);
Det = 12.0*r1*r1*r1/(1.0 - r1*r1);
vv = BoxSize*(2.0*BoxSize + 1.0)/6.0;
for j = 2:numberpoints - BoxSize
dhh = SumOfSumsSquared(j + BoxSize) - SumOfSumsSquared(j-1);
dhu = SumOfSums(j + BoxSize) - SumOfSums(j-1);
dhv = SSc(j + BoxSize) - SSc(j-1) - dhu*j;
s = s + dhh - (dhv*dhv +dhu*dhu*vv - dhv*dhu*BoxSize)*Det;
j = j + 1;
end
den = (numberpoints - BoxSize)*(BoxSize + 1.0);
Fluctuation = sqrt(s/den);
log_points_in_box(iteration,1) = log10(BoxSize);
log_Q(iteration,1) = log10(Fluctuation);
show_results(iteration,:) = [ iteration BoxSize Fluctuation log_points_in_box(iteration,1) log_Q(iteration,1) ];
iteration = iteration + 1;
% update the box size
TempBoxSize = TempBoxSize*LogScaleFactor;
while round(TempBoxSize) < BoxSize + 1.0
TempBoxSize = TempBoxSize*LogScaleFactor;
end
BoxSize = round(TempBoxSize);
end
% got all boxes; now calculate H via trendline
r_trend = corrcoef(log_points_in_box, log_Q);
coefs = polyfit(log_points_in_box, log_Q,1);
r_line = polyval(coefs,log_points_in_box);
% calculate dimension and Hurst
h(kk) = coefs(1);
D = 2-h(kk);
end
H{k}=h;
end
end

Sign in to comment.

More Answers (1)

Beautiful! Many thanks!
Sorry one last thing, I promise! When running this code the resulting cells are saved in a single row rather than in the same shape that the cell array p_windows11 was originally in.
I am looking to have the cells in H saved in the same sequence as in p_windows11. Meaning that all the results from the cells in the first column are saved column-wise first in H as well.
Example:
H
1x47 = H{1,1}
1x43 = H{2,1}
Sorry for my poor experience in matlab!

2 Comments

function [H]=dfaedit(data)
format short g
H=cell(size(data));%just add this line at the beginning
Perfect! This is exctly what I needed! If my project gets published, you're getting special thanks!

Sign in to comment.

Categories

Asked:

on 26 Jan 2022

Commented:

on 27 Jan 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!