How to write a function for this simple purpose?
2 ビュー (過去 30 日間)
古いコメントを表示
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
......
0 件のコメント
採用された回答
Image Analyst
2019 年 10 月 26 日
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 件のコメント
Image Analyst
2019 年 10 月 26 日
編集済み: Image Analyst
2019 年 10 月 26 日
Just modify your lookup table. Or do you just want to take the log10 of the value? Like
B = log10(A/5);
その他の回答 (2 件)
John D'Errico
2019 年 10 月 26 日
編集済み: John D'Errico
2019 年 10 月 26 日
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
David Hill
2019 年 10 月 26 日
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 件のコメント
David Hill
2019 年 10 月 26 日
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
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!