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

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.

댓글을 달려면 로그인하십시오.

 채택된 답변

Mathieu NOE
Mathieu NOE 2021년 11월 26일
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

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
Bjorn Gustavsson
Bjorn Gustavsson 2021년 11월 26일
편집: Bjorn Gustavsson 2021년 11월 26일
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!
My pleasure !

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Polynomials에 대해 자세히 알아보기

질문:

2021년 11월 26일

댓글:

2021년 11월 26일

Community Treasure Hunt

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

Start Hunting!

Translated by