Return values from nested if statement in function

I'm trying to write a function that will take in the vectors date, pH and depth, the minimum and the maximum depth. It will return new date and pH vectors that only contain the data when the depth was >= the minimum or < the maximum. I've tried a few variations of the code, but everything either doesn't give a result or throws an error. Below is my most recent attempt, but it is only returning the empty vector, which isn't correct. The pH, date and pressure_dbar (which is the depth) variables were imported from a .mat file and work properly. Any tips on why this isn't working properly would be appreciated.
minimum = min(pressure_dbar);
maximum = max(pressure_dbar);
function [newDate, newpH] = oceanpHdepth(date, pH, pressure_dbar, minimum, maximum)
for i = 1:length(date)
for j = 1:length(pH)
if (pressure_dbar >= minimum)
if (pressure_dbar < maximum)
newDate = date(i);
newpH = pH(j);
end
end
end
end
end

 Accepted Answer

Using loops is a very inefficient way to perform this task: MATLAB is most efficient when operating on complete arrays, for example using vectorized operations or matrix indexing. So it is much better to simply generate the indices once, and then apply them to the complete input vectors, like this:
function [newDate, newpH] = oceanpHdepth(date, pH, pressure_dbar, mnv, mxv)
idx = pressure_dbar >= mnv & pressure_dbar < mxv;
newDate = date(idx);
newpH = pH(idx);
end
PS: the vector idx is called a "logical index", you can read about it here:

8 Comments

hey, thanks so much for this. Do you know for any reason why only the newDate vector would be displaying when the function is called and not the newpH vector also?
You need to specify both of them as outputs:
[outDate, outpH] = oceanpHdepth(...)
How to call functions is explained in the introductory tutorials, which are recommended for all beginners:
I have already done so, as per my code above?
No worries if you aren't sure, but I've separated the code into sections (different pressure_dbar values) using this function. Do you know how I'm to plot this? For example:
pHsurface = oceanpHdepth(date, pH, pressure_dbar, 0, 9);
I want to then plot pHsurface against the pressure_dbar. But doing plot(pHsurface, pressure_dbar) throws an error as the vectors aren't the same length?
No you haven't done so. Look at your call
pHsurface = oceanpHdepth(date, pH, pressure_dbar, 0, 9);
only one output is being accepted. Now look at how Stephen recommended you call it:
[outDate, outpH] = oceanpHdepth(...)
See? Two outputs are being accepted. Again, it could have been solved by now if you'd just have given your entire code (function and test code that calls the function) and the data file(s) to make it easy for us to help you the first time.
Again, you didn't ask for the code until you got all mad and said you refused to help anymore, so don't put that on me. Why are you still here if you're going to try and insult me every response? Stephen understood and gave me a fantastic answer without needing to know the stuff you were asking for, even though I told you you didn't need it. I'm new to this and trying to get some help, on most forums people get mad and down vote your question if you just post the code for them to fix up. You really don't have to be so rude.
I thought that by making the function header return two outputs, that that would automatically return both vectors when called as that is the output. I see now that that's not the case, but then how do you assign the output to a single variable? Am I able to do this?
[surfaceDate, surfacepH] = oceanpHdepth(date, pH, pressure_dbar, 0, 9);
pHsurface = [surfaceDate, surfacepH];
@Brittany Toohey: once you have called your function with two outputs:
[outDate, outpH] = oceanpHdepth(...)
then you can easily concatenate them into one numeric matrix using []:
outMat = [outDate,outpH];
or otherwise they could be combined onto one cell array, or into one structure, or one table, or... it depends on your use case (i.e. what you intend to do with this variable).
Awesome, thanks heaps. I'd tried that, but keep getting the error: Error using datetime/horzcat (line 1260) All inputs must be datetimes or date/time character vectors or date/time strings.
I plan to try to plot pHsurface against the pressure_dbar corresponding value btw
It is not possible (with some exceptions) to concatenate arrays of different types/classes. You will need to convert them to the same type first, otherwise it should be possible to plot them in one plot call but as separate inputs:
plot(X1,Y1,'x',X2,Y2)
or
plot(X1,Y1)
hold on
plot(X2,Y2)
read the plot help for more info on these.

Sign in to comment.

More Answers (1)

This looks weird to me:
for i = length(date)
First of all, date() is a built in function, normally, but you destoryed it by passing in a variable for it. I'm not sure what data is , but the length of it is a single number. Let's say it's 9 for the sake of illustration. So you have
for i = 9
Now, that's not in the normal form of "for i = start:step:stop", though you can do it. So the loop will execute only once with a value of 9 for i.
So then if you every get to the line
newDate = date(i);
it will take the 9th element of date, which is the last element since i was just the length of date. Seems weird. But then you do
newpH = pH(i);
So now you're taking the 9th element of pH - I don't even know if it has 9 elements. But whatever, this code will not do any kind of looping while changing the value of i. It will execute just one with i having one value (whatever the length of date is).
Even if you did loop and change i, you'd be continually overwriting the same value for newDate and newpH because you're not indexing those variables - they're single element scalars, not multiple element arrays.
I'm not sure how to fix it because I don't know what values date and pH have coming in, nor do I know exactly what you want to do.

7 Comments

Yeah that was stupid of me. I initially didn't have the for loop and didn't think it through well when I added it. I just want to be able to somehow create new vectors for pH and date where the pressure_dbar is >= minimum and < maximum for both the pH and date. But I'm unsure how to do this with multiple vectors.
I might be able to fix it if you tell me what you're passing in for date, pH, pressure_dbar, minimum, maximum.
pressure_dbar, pH and date are all separate vectors - 546x1. Minimum and maximum were in the code - min(pressure_dbar) and max(pressure_dbar)
That's not much help. Please give code that generates values for those variables, either by assigning them or by reading in from a file.
I literally just load the .mat file that contains those variables as I said in my first post, you don't really need to know anything about them to do what I'm trying to do.
Since you're unwilling to give code for reading in the .mat file and unwilling to attach the file like I asked to make it easy for me to help you, I think I'll just have to let my original answer stand. Good luck though. Perhaps someone else will help.
I'm not unwilling, it just seemed like a waste of time to you. The reading in is just load('HOTSdata.mat'); which works for every other function I use it on, so it has nothing to do with that. And you didn't once ask me to attach any file. But anyway, you didn't sound like you had a clue what I'm trying to do anyway, so whatever. Thanks anyway.

Sign in to comment.

Categories

Asked:

on 13 Apr 2017

Edited:

on 14 Apr 2017

Community Treasure Hunt

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

Start Hunting!