How to write a function for this simple purpose?

2 visualizaciones (últimos 30 días)
Leon
Leon el 26 de Oct. de 2019
Comentada: Leon el 26 de Oct. de 2019
I have a variable A. If it is between 5 and 50, B = 10, etc. (like the below). How do I write a function so that B = f(A)? Thanks!
What I listed below are just some examples, and in reality, my A and B could be infinitiely small or infinitely big. For example, I could have an A value between 5x10^-19 and 5x01^-18, in that case B should be equal to 1x10^-18.
%A B
......
0.005-0.05: 0.01
0.05-0.5: 0.1
0.5-5: 1
5-50: 10
50-500: 100
500-5000: 1000
......

Respuesta aceptada

Image Analyst
Image Analyst el 26 de Oct. de 2019
Try this
b = f(.9) % For example;
b = f(22) % For example;
b = f(333) % For example;
b = f(444) % For example;
function B = f(A)
%A B
lookupTable = [
0.005,0.05, 0.01
0.05,0.5, 0.1
0.5,5, 1
5,50, 10
50,500, 100
500,5000, 1000];
row = A > lookupTable(:, 1) & A <= lookupTable(:, 2);
B = lookupTable(row, 3);
end
  3 comentarios
Image Analyst
Image Analyst el 26 de Oct. de 2019
Editada: Image Analyst el 26 de Oct. de 2019
Just modify your lookup table. Or do you just want to take the log10 of the value? Like
B = log10(A/5);
Leon
Leon el 26 de Oct. de 2019
Editada: Leon el 26 de Oct. de 2019
I like this direction! I think the below will do the trick:
B = 10^ floor( log10(A/5)+1 )

Iniciar sesión para comentar.

Más respuestas (2)

John D'Errico
John D'Errico el 26 de Oct. de 2019
Editada: John D'Errico el 26 de Oct. de 2019
Here are other approaches that are nicely vectorized, but do not require you to set explicit tests for each bin. For example, suppose you had literally dozens of bins? You don't want to hard code those tests. So instead, you need to learn and use the tools in MATLAB that will allow you to solve the problem in a fully general way.
I've done it here in a way that assumes Z can be any positive value. Where A is below 0.005, it will return 0.001. Where A is greater than 5000, it will return 10000. I was fairly arbitrary in those choices, but it is important that you consider what will happen if the sky actually is falling, and you take care of those degenerate cases. (Good software can be described as a worrywort: ie., always worrying about what will I do if event X happens? How about Y? And, god forbid, what about Z? The best software lets the user down softly whenever possible, and when not, it should provide a clear error explanation to help the user to identify and fix any problems.)
I suppose I could have chosen to make the end conditions return 0 and inf as an alternative.
function B = f(A)
bins = [0 0.005 .05 .5 5 50 500 5000 inf];
vals = [0.001 .01 .1 1 10 100 1000 10000];
ind = discretize(A,bins);
B = vals(ind);
end
Now let me try it:
f([.000001 .002 .2 .6 12 100 1e12 inf])
ans =
0.001 0.001 0.1 1 10 100 10000 10000
So it works as designed. As I said, the nice thing is it allows you to define the function without needing any specific tests. I could have written the tool so that you actually pass in the bin boundaries and values as arguments too, I suppose. That would be more general yet.
Now, could I have written this for the very specific case here, without using discretize? Actually, yes, because you have chosen very simple bin boundaries. In fact, I can do it in one line of code, just using a function handle..
f = @(A) 10.^floor(log10(A*2));
This line of code will work, but note that it has no effective boundaries on the positive real line, as long as you do not exceed the reasonable limits imposed on you by use of double precision arithmetic.
f([.0000000000009, 6, 130000])
ans =
1e-12 10 1e+05
That may or may not be what you want. But it is trivial to fix if you did want limits. For example:
f = @(A) 10.^max(-3,min(4,floor(log10(A*2))));
Again, it works with no problem. Here the lower limit is arbitrarily 0.001, and the upper limit is 10000.
f([.0000000000009, 6, 130000])
ans =
0.001 10 10000
  2 comentarios
David Hill
David Hill el 26 de Oct. de 2019
Very nice!
Leon
Leon el 26 de Oct. de 2019
Beautiful!
Thank you so much.

Iniciar sesión para comentar.


David Hill
David Hill el 26 de Oct. de 2019
function c = f(c)
c(c>=.005&c<.05)=.01;
c(c>=.05&c<.5)=.1;
c(c>=.5&c<5)=1;
c(c>=5&c<50)=10;
c(c>=50&c<500)=100;
c(c>=500&c<=5000)=1000;
end
  3 comentarios
David Hill
David Hill el 26 de Oct. de 2019
function c = f(c)
for i=1:length(c)
a=-10;%whatever is maximum expected (10^10)
while round(c(i),a)==0
a=a+1;
end
c(i)=round(c(i),a);
x=num2str(c(i));
x=str2double(regexp(x,'[1-9]','match','once'));
c(i)=c(i)/x;
end
Leon
Leon el 26 de Oct. de 2019
Thank you for another approach of doing this!

Iniciar sesión para comentar.

Categorías

Más información sobre MATLAB en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by