Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
Hi everyone. I am a little bit confuse using lookup command. I'd like to match the Ixx_match to the nearest given Ixx and select the equivalent profile. I attached the exel file so that you can follow the readexel command .
Solved! Go to Solution.
Now, the attached prime file prevents the error by exchanging each z in a lookup function with the boundaries of the input array.
Along the way I made the function a bit more generic.
Sucess.
Luc
Oops. Corrected attachment.
The Lookup function(s?) don't seem to work with units.
Then there is no easy way to get the 'nearest' matching value without using tolerance (which would get you ALL values within the band) and without programming (I'm limited to prime express).
But I managed to do it:
Basically what the IF statment does is to check the first of the greater-or-equal values list and the last of the less-than-or-equal values for the closest match, and then select the corresponding modifier to select the value from the other array.
Mind, there is no error handling. If z=20 you get an error.
Success!
Luc
So you used modifier. I will try this in Mathcad prime 3.1
Now, the attached prime file prevents the error by exchanging each z in a lookup function with the boundaries of the input array.
Along the way I made the function a bit more generic.
Sucess.
Luc
Oops. Corrected attachment.
If z have 3 values in matrix it is possible also to have a 3 results ?
Or better to use matrix row
This still need to improve . As you can see the z value, the range once exceeded it should select the next profile.
That's a bug in your question. You wanted the nearest, not the 'nearest upper'.
'Nearest upper' makes life simpler:
Luc
This one make sense for nearest upper.
Thank you.
Cheers!
Your initial approach works and lookup can deal with units. Thats exactly is the problem here.The values are converted to base units and thats m^4. So the values are very small around 10^-6, 10^7. lookup uses the value of the system variable TOL to decide if a value is "near" or not. Thats the reason you get all values with your approach - they all are "near". You can cope with that by setting TOL:=10^-7, but thats a quite unreliable "solution".
Its a shame that we have to resort to complicated constructions like Luc's and that we have no real "nearest" at our disposition. Most of the time we are better off writing our own "lookup" (which we can't do in Prime).
BTW - can anybody explain the difference between the modifiers "eq" and "near"? Seems they do the very same!
According your vector of three values which you want to be evaluated at once:
Turn select(..) into a function with just one argument -> sel(z):=select(z,I.xx,profile) and then call sel(z) but vectorize that call. This should work.
WE
Can you please show me your approach . I attached the file for you reference,
Thank you
I can't read files in 3.1 format (only P 3.0).
Here is what I was talking about:
WE
EDIT: I just added a different select routine (requires programming so it won't work in Express) which is self contained and still allows the two data vectors as arguments:#
I could not get it to work with units, even if I had an exact match as search value (z).
Regarding the difference eq<=>near.
See the excerpt that Lex provided from the help:
"eq" checks (or, at least, is supposed to check) for (exact) equality.
"near" then checks within limits as set by TOL.
If the actual behaviour of prime differs from this:.... shame on PTC.
Luc
Omitting the modifier defaults to "eq". I use match here but all applies to lookup, too.
I found a small difference between "eq" and "near", but I cannot explain it (last two lines with TOL set lower than the difference between z and the exact value we are searching. Looks like "near" does what we want if we set TOL low enough. Thats bad - that tolerance should be an optional argument to match and lookup.
"near" should work as if TOL is set to 0 in all cases. For other purposes we have "range".
I tried this, I think this make all complete
What if z is more than Ixx how I will write this is the program . When I tried this all the matrix value was disappeared.
First - you don't need change TOL to use the routines I provided.
Those changes are in the sheet because of my answer to Lucs comments.
The failure you encounter is exactly what my comments in the file are telling you.
For (my) convenience I used a simpler version of the lookup sequence which fails, if no grater value is found.
One value in your vector z is 3600, lookup cannot find any value greater than that in I.xx and so the call fails.
Solution: Use Luc's approach, you know, the combination of min and max which he creates exactly to cope with this one problem.
Why did you define that extra function sel()?
I thought that you wanted to keep the function more versatile an so accommodate for the two vectors as arguments.
If you don't like this, simply omit the arguments S and L in select() and replace S and L in the lookup sequence for I.xx and profiles.
As you obviously are not restricted to the Express version, here is a different approach.
If the value is too high, an error string is returned. If you want the last Profile string being returned, replace "value too high" by "profile[last(profile)".
WE
if I will remove TOL then the answer will be like this
With TOL the result is correct
Lex Dante wrote:
if I will remove TOL then the answer will be like this
With TOL the result is correct
I see. I have not tested my sheet with default TOL.
Thats crazy and ridiculous and sure not as it should be. The reason for that behavior is, that the values, which are compared, all are in the range 10^-7, 10^-6 and lookup considers them as being all equal (within the value of TOL).
So we learn that its better not to use the built-in routines match and lookup - at least not in combination with smaller data values.
Better we write our own routines.
Here are two different approaches. While I would prefer to add the two data vectors as additional arguments for more versatility and to keep it all nice and tight, you seem to prefer to use global data vectors from within your routines - so thats the way I implemented those two routines.
Werner
P.S.: If you don't like the idea of having to use vectorize in the main calculation part of the sheet, you can use either
or even better
Werner