Switch statement using intervals.
Ältere Kommentare anzeigen
i have a homework question which aska to solve same question using if as well as switch commands. it has specific intervals as shown below. Got done with if but dont know how to put these intervals in switch. Write a MATLAB function that determines type of soil by taking soil particle size as input. For this question,
a) use if – elseif - else statement.
b) use switch – case statement.
You may refer to following soil classification table:
soil type lower bound(mm) upper bound(mm)
boulders 200 -
cobbles 60 -200
gravel 2 -60
sand 0.06- 2
silt 0.002- 0.06
clay - 0.002.
3 Kommentare
KSSV
am 16 Nov. 2016
What you have tried?
Syed Ali SHAH
am 16 Nov. 2016
Syed Ali SHAH
am 16 Nov. 2016
Antworten (3)
Guillaume
am 16 Nov. 2016
This does not answer your question but may be helpful to others. The proper way of doing this in matlab would be:
sizes = [0.001 0.03 0.5 0.7 1.5 3 45 70 105 210 250];
discretize(sizes, [-Inf 0.002 0.06 2 60 200 Inf] , 'categorical', {'clay', 'silt', 'sand', 'gravel', 'cobbles', 'boulders'})
No loops, if or switch statements required.
2 Kommentare
Thomas Michiels
am 18 Sep. 2018
if i was the question writer, i would be happy with this answer, getting something better then i asked for. This should be the accepted answer as the other answers also don't give a solution, only as why doing so is anti idiomatic and should be avoided
Walter Roberson
am 18 Sep. 2018
Bearbeitet: Walter Roberson
am 18 Sep. 2018
Thomas, I gave an actual solution. It involved changing one word, x to true . We discussed why it wasn't a preferred solution, but it was still a solution. The user also explained why using discretize() was not suitable for their purposes, but that my solution was suitable for them.
Walter Roberson
am 16 Nov. 2016
In your code, change
switch x
to
switch true
and make sure to give an Otherwise.
Using a logical constant for the switch and using logical expressions for the cases is obscure but it is defined.
6 Kommentare
Awesome! This is exactly what I was searching! I have to use intervals because my input can be any real number, and I cannot use that 'discretize' method because I have to do actions depending on the case (ok, it is basically possible if I define and call functions for each case but that is clumsy). So, my best option before this neat solution was to use ugly sequence of if - elseif - elseif - etc...
I cannot use that 'discretize' method because I have to do actions depending on the case [..] that is clumsy
In all likelyhood it requires the grand total of three lines! One line to define an array of anonymous function, one call to discretize, one line call the appropriate function by indexing the function array with the index returned by discretize.
If you do use switch as above, pay attention to Walter's comment: "using logical expressions for the cases is obscure". What that means is you better put a lot of comments explaining exactly what is going on, how the switch works, why the value after the switch is a constant instead of a variable, etc. You can be certain that whoever (including you) looks at your code in 6 months will not understand what is going on since it's such an odd construct.
And don't forget Walter's "and make sure to give an Otherwise."
Petri M
am 2 Dez. 2017
It is not just three lines. I am not talking about simple actions which could be defined as anonymous function in a single line, but series of actions, which require several lines. Of course, if the series of actions would be similar in every case and only some values are changed, then you could just call a function with different parameters, but sometimes there is no common procedure that could cover all cases.
Also, this switch-method is definitely the clearest and the most readable way of implementing the selections in the case, where I am just currently using it. It is actually so self-explanatory, that it does not even require comments. Below you can see the template. By the way, you just might happen to know that the bandwidth limits are nominal LTE signal bandwidths... Of course, the way how the intervals here are defined, require that the cases are in ascending order, but that is the most natural way of arranging them. And also it is natural to have that 'otherwise' case at the end for all bandwidths above 15e6.
So, there are surely a lot of use cases where 'discretize' is the best way of implementing the selection, but there are also use cases where switch-method is the clearest, the most readable, and the easiest way. I do not know what method is the most efficient in terms of processing speed, but in this case I do not care about the speed because the process is not so time critical.
switch true
case (bw<=1.4e6)
...
series of actions
...
case (bw<=3e6)
...
series of actions
...
case (bw<=5e6)
...
series of actions
...
case (bw<=10e6)
...
series of actions
...
case (bw<=15e6)
...
series of actions
...
otherwise %When bw is above 15e
...
series of actions
...
end
Walter Roberson
am 2 Dez. 2017
"It is actually so self-explanatory, that it does not even require comments"
I have been using MATLAB for roughly 25 years, and I go through a lot of Questions here. With the perspective of my considerably greater than average experience with MATLAB, I can tell you that this use of a constant in the switch and a logical expression in the case really is obscure.
In almost all programming languages, switch case labels need to be constants, and unique, and in those languages it is common for the compiler to optimize through some kind of internal jump table using indexing (possibly after hashing) to go directly to the correct code more efficiently than testing each case in sequence. People are familiar with switch statements will bring that baggage from other languages with them, and are going to say, "Wait, what??" when they see this code, and are going to ask questions like, "Wait, is this order-sensitive or is it only allowed for at most one case to match??"
When you use the MATLAB switch statement in this manner for anything other than proving that it could be done, then you should almost always instead rewrite it as if/elseif sequences, or as table-driving calls.
if bw <= 1.4e6
actions 1
elseif bw <= 3e6
actions 2
elseif bw <= 5e6
actions 3
..
else
...
end
Guillaume
am 3 Dez. 2017
As evidence that the syntax is very obscure and unusual (I actually had to look the documentation of switch when Walter first posted his answer), you only have to look at the first tip in the tip section of switch documentation:
A case_expression cannot include relational operators such as < or > for comparison against the switch_expression.
Yet, here we are with a case expression which include a relational operator:
case bw<=1.4e6
It's actually an interesting dilemma, one part of switch documentation allows the above construct, yet another part disallows it. So, I'm not even sure that Walter's statement that "it is defined" is actually correct. Something to discuss with Mathworks...
As for not requiring comments, you're of course free to do what you want. In my opinion, more comments than necessary is always better than not enough. In this particular case, I would argue that anybody who comes across switch true and doesn't immediately starts to wonder what is going on either is a true matlab expert or doesn't understand what they're reading.
As Walter implies, in most other languages, the current construct is not even allowed. A normal switch consists of switch expression_whose_value_is_unknown ... case _constant_expression, often simplified to switch variable_name ... case _constant. And basically says, pick whichever case constant corresponds to the value of the switch variable. Here we're turning it on its head and say pick whichever case variable is equal to the switch constant.
Walter Roberson
am 3 Dez. 2017
"A case_expression cannot include relational operators such as < or > for comparison against the switch_expression."
This situation does not do that: the comparisons are against other expressions. And the tip is not correct:
var = true;
switch var
case var > false
disp('dat!')
otherwise
disp('?')
end
It is just hardly ever useful to use relational operators in the cases to test against the switch expression, because the use of relational operators in the cases can only work if the switch expression was logical or 0 or 1 (because equality tests are used)
So...
>> var = 1;
switch var
case var > 0
disp('dat!')
otherwise
disp('?')
end
dat!
but you run into odd situations like
>> var = 0; switch var
case var == 0
disp('var 0')
otherwise
disp('var 0 false')
end
var 0 false
>> var = 1; switch var
case var == 0
disp('var 0')
otherwise
disp('var 0 false')
end
var 0 false
In the first case with var = 0, var == 0 is true, but true is 1 and 1 ~= 0 (the switch expression value) so the first case is not met. In the second case with var = 1, var == 0 is false, and false is 0 and 0 ~= 1 (the switch expression value) so the second case is not met.
And then you get
>> var = 0; switch var
case var ~= var
disp('var is not equal to itself')
otherwise
disp('var is equal to itself')
end
var is not equal to itself
0 ~= 0 is of course false, which is 0, but 0 is equal to the switch expression value of 0, so the case is considered true!
Petri, although perhaps you might glance at that last example and find it so obvious that it does not even need a comment, I tell you that the rest of us need a comment for it!
Bruno Luong
am 18 Sep. 2018
edges=[-Inf 0.002 0.06 2 60 200 Inf];
[~,intnum] = histc(x,edges);
switch intnum
case 1 % clay
processclay(x)
case 2 % silt
...
end
Kategorien
Mehr zu Programming finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
