How to find whether an array is logarithmically spaced

I have linearly, logarithmically and randomly spaced arrays. I need to tell them apart, but I am having trouble to determine whether an array is logarithmically spaced. Help is most appreciated!

2 Comments

What have you tried, have you looked at how the spacing varies with the magnitude of the elements?
I am using this code to determine whether it is linearly spaced:
range(x(2:end)-x(1:end-1)) % if this is equal to zero I accept that the array is linearly spaced. (where x is a row vector)
However, I could not yet find a good way to determine whether the arrays are log-spaced, because I need to tell apart between log-spaced and randomly spaced arrays as well.

Sign in to comment.

 Accepted Answer

well
if you have a criteria that works for lin spaced arrays (like checking that std(diff(y)) is always below a very low threshold)
you can easily covert a log speced array to a lin spaced array by taking the log of it
demo :
y_log = logspace(1,3,100);
% nb : y = 10 .^ linspace(d1, d2, n);
y_lin = log10(y_log); % conversion from log to lin spacing
check = std(diff(y_lin))
check = 2.1980e-16

7 Comments

Using std is a good way to understand whether the array is linearly spaced or not. However, this method does not differentiate between randomly or logarithmatically spaced arrays.
??
I have showed you above how a log spaced array could be converted back to lin spaced and then checked
if you do the std test on a random vector you will see the higher value of std
So you have tried this, have you?
...and by this I mean: you should probably do the bulk of your homework...
I am not asking for you to create a logspace vector. Just want to see if this vector is log-spaced or not:
durationList=[0.9, 1.25, 1.4, 1.75, 2.2, 2.75, 3.45];
well, I have multiple of those to be determined for their spacing
this was just for the sake of the demo - as you didn't provide the data in first place.
below is a refined approach, as your data seems to hat a bit of outlier presence
it's basically a fit test (with R² correlation computation) between your data and a linear and log model
see the log model fit better (R² = 0.9937) vs the linear model (R² = 0.9581)
so this can help you decide which model best fits your data
clc
clearvars
% data
durationList=[0.9 1.25 1.4 1.75 2.2 2.75 3.45]; % assumed a log spacing
% try 1 : if it's a linear spacing we can try to fit a 1st degree
% polynomial
x = (1:length(durationList));
y = durationList;
% Fit a polynomial p of degree "degree" to the (x,y) data:
degree = 1;
p = polyfit(x,y,degree);
% Evaluate the fitted polynomial p and plot:
f = polyval(p,x);
eqn = poly_equation(flip(p)); % polynomial equation (string)
Rsquared1 = my_Rsquared_coeff(y,f); % correlation coefficient
figure(1);plot(x,y,'o',x,f,'-')
legend('data',eqn)
title(['Data fit - R squared = ' num2str(Rsquared1)]);
% try 2 : if it's a log spacing we can try to fit a 1st degree
% polynomial to the log of the data
x = (1:length(durationList));
y = log10(durationList); % convert log spacing to lin (to be checked)
% Fit a polynomial p of degree "degree" to the (x,y) data:
degree = 1;
p = polyfit(x,y,degree);
% Evaluate the fitted polynomial p and plot:
f = polyval(p,x);
eqn = poly_equation(flip(p)); % polynomial equation (string)
Rsquared2 = my_Rsquared_coeff(y,f); % correlation coefficient
figure(2);plot(x,y,'o',x,f,'-')
legend('data',eqn)
title(['Data fit - R squared = ' num2str(Rsquared2)]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Rsquared = my_Rsquared_coeff(data,data_fit)
% R2 correlation coefficient computation
% The total sum of squares
sum_of_squares = sum((data-mean(data)).^2);
% The sum of squares of residuals, also called the residual sum of squares:
sum_of_squares_of_residuals = sum((data-data_fit).^2);
% definition of the coefficient of correlation is
Rsquared = 1 - sum_of_squares_of_residuals/sum_of_squares;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function eqn = poly_equation(a_hat)
eqn = " y = "+a_hat(1);
for i = 2:(length(a_hat))
if sign(a_hat(i))>0
str = " + ";
else
str = " ";
end
if i == 2
eqn = eqn+str+a_hat(i)+"*x";
else
eqn = eqn+str+a_hat(i)+"*x^"+(i-1)+" ";
end
end
eqn = eqn+" ";
end
That is just a great approach Mathieu! Thank you so much!

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

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

Start Hunting!