Shorter version of IF(ISERROR(...)) - excel

I'm wondering if there is a way to check if a formula returns an error, and if not, use the value found, without doing the following:
=IF(ISERROR(A1/B1), 0, A1/B1)
The syntax I'm looking for is something like this:
=EQ([value_if_not_error], [value_if_error])
The solution might contain more stuff, IF and ISERROR is perfectly fine, as long as I avoid having the main function several times in each cell. The reason why I want to do this is that my equations are quite long and the readability is drastically reduced when I have to write the equation twice, or even more (if several ifs).
Is there a simple solution to this?

Try
=IFERROR([formula], [value_if_error])

Related

Plug Intermediate Variables into Equation

I have a MATLAB symbolic math script that calculates a couple really large matrices for me, which I then convert into a function via matlabFunction. The problem is that the matrices contain integrals, and when matlabFunction converts it it creates loads of intermediate functions (about 200, which is why I'm trying not to do this manually) which contain the variable I'm integrating over, causing errors because the variable isn't defined outside the integral() call. In the end I'm left with a bunch of nested equations that look like:
M = integral(#(s)f(t1,t2,t3,t4)) <-- t1 = g(et1,et2,et3,....) <-- et3 = h(s)
They're not all functions of every other one, but theres a lot of dependencies between them becuase of how MATLAB tried to simplify the expression. The error gets thrown when MATLAB tries to evaluate et3, notices it has an s in it (which is find to be in M because of the integral), then breaks because s isn't defined.
So far I've tried messing with the commands in MATLAB to make them stop generating terms like that but everything I did seemed to make it worse, so I've moved to excel where my current idea is something like:
Start with each equation in it's own cell
Break each cell at "=" to get the actual equations on their own
Find each placeholder variable and substitute the actual expression in
I've been trying to write a macro or lambda function for this (admittedly I don't really know how to do either of those well) but I keep getting stuck because I basically need the script to take a list of variables I want to get rid of and just keep substituting until they're all gone, but I'm not really sure how to do this in Excel.
I've also tried to use a couple "multiFindAndReplace" scripts online that let you find and replace vectors of data but none of them seem to work for this case and the SUBSTITUTE command would end up needing to be nested dozens of time to get it do what I want.
Does anyone have ideas on what to do here? Or is there a setting I'm missing in MATLAB to suppress all the intermediate terms?
EDIT: As soon as I posted this I had another idea - it looks like MATLAB generates the terms such that the et terms can't depend on one another and that no et term appears in more than one t term.
(also this is my first question, let me know if I put it in the wrong place)

How do I avoid repeating long formulas in Excel when working with comparisons?

I know that something like the following
=IF(ISERROR(LONG_FORMULA), 0, LONG_FORMULA)
can be replaced with
=IFERROR(LONG_FORMULA, 0)
However I am looking for an expression to avoid having to type REALLY_LONG_FORMULA twice in
=IF(REALLY_LONG_FORMULA < threshold, 0, REALLY_LONG_FORMULA)
How can I do this?
I was able to come up with the following:
=IFERROR(EXP(LN(REALLY_LONG_FORMULA – threshold)) + threshold, 0)
It works by utilizing the fact that the log of a negative number produces an error and that EXP and LN are inverses of each other.
The biggest benefit of this is that it avoids accidentally introducing errors into your spreadsheet when you change something in one copy of REALLY_LONG_FORMULA without remembering to apply the same change to the other copy of REALLY_LONG_FORMULA in your IF statement.
Greater than comparisons as in
=IF(REALLY_LONG_FORMULA>=threshold,0,REALLY_LONG_FORMULA)
can be replaced with
=IFERROR(threshold-EXP(LN(threshold-REALLY_LONG_FORMULA)),0)
Example below (provided by #Jeeped):
For strict inequality comparisons use SQRT(_)^2 as pointed out by #Tom Sharpe.
If you're comparing against a threshold amount, I would consider checking out ExcelJet's recent blog post about
Replacing Ugly IFs with MAX() or MIN().
Also, the MAX() and MIN() functions are much more intuitive than using lessor known functions like EXP() and LN().
Comparing Ln Exp with SQRT ^2:-
because SQRT(0) gives 0 but ln(0) gives #NUM!
So you can choose which one to use depending whether you want the equality or not.
These also work for negative numbers - in theory.

Functional alternative to caching known "answers"

I think the best way to form this question is with an example...so, the actual reason I decided to ask about this is because of because of Problem 55 on Project Euler. In the problem, it asks to find the number of Lychrel numbers below 10,000. In an imperative language, I would get the list of numbers leading up to the final palindrome, and push those numbers to a list outside of my function. I would then check each incoming number to see if it was a part of that list, and if so, simply stop the test and conclude that the number is NOT a Lychrel number. I would do the same thing with non-lychrel numbers and their preceding numbers.
I've done this before and it has worked out nicely. However, it seems like a big hassle to actually implement this in Haskell without adding a bunch of extra arguments to my functions to hold the predecessors, and an absolute parent function to hold all of the numbers that I need to store.
I'm just wondering if there is some kind of tool that I'm missing here, or if there are any standards as a way to do this? I've read that Haskell kind of "naturally caches" (for example, if I wanted to define odd numbers as odds = filter odd [1..], I could refer to that whenever I wanted to, but it seems to get complicated when I need to dynamically add elements to a list.
Any suggestions on how to tackle this?
Thanks.
PS: I'm not asking for an answer to the Project Euler problem, I just want to get to know Haskell a bit better!
I believe you're looking for memoizing. There are a number of ways to do this. One fairly simple way is with the MemoTrie package. Alternatively if you know your input domain is a bounded set of numbers (e.g. [0,10000)) you can create an Array where the values are the results of your computation, and then you can just index into the array with your input. The Array approach won't work for you though because, even though your input numbers are below 10,000, subsequent iterations can trivially grow larger than 10,000.
That said, when I solved Problem 55 in Haskell, I didn't bother doing any memoization whatsoever. It turned out to just be fast enough to run (up to) 50 iterations on all input numbers. In fact, running that right now takes 0.2s to complete on my machine.

VBA Exp() Overflow

Here's a very easy question for the VBA guys. I'm running Newton's method on some functions, and occasionally I find a guess that I can only assume overflows the Exp() function (and stops the code). What suggestions do you guys have to simply handle this case? (Maybe some sort of error handling?)
If Newton's method fails because of this or any sort of blowup, I would like to proceed onto my bisection code below that point.
By the way, I have thought about maybe taking logs to make this situation less likely, but to be honest I am working with some math I do not yet completely understand, and I would like to handle the case of Newton's method failing in any case first.
Disclaimer: I'm a complete VBA beginner, so any suggestions would be read and appreciated. Thanks in advance.
Edit: I've been asked to post the code. First, thanks for reading. Unfortunately, I can't post the entire code due to business reasons, but I can give the very barebones outline. I've created a module and a function. Inside this function, I have:
Newtons Method Loop
Bisection Loop
Inside the Newton's method loop, I've traced to a point where I have a next guess of something around 28,000 or so, and I am assigning to a variable h the value Exp(28,000) or roundabouts. The debugger breaks at that point; my code essentially exits, and whatever value my function should be returning produces #VALUE! in my cell.
I know this is not a lot of information, but I hope (and think) it should be enough. Correct me if I am wrong.
Edit 2: If all else fails, I'm going to explicitly catch too large values, but I wonder if there is a more robust and elegant solution.
Not surprising it will overflow given that Exp(28,000) is 1.8x1012160, the maximum value you can pass to Exp is ~709.
If you want to exit your loop if you encounter a value that is too large, just check the value before passing it;
function Newton
const MAX_EXP_ARGUMENT as double = 709.782712893#
do ....
if (abs(var) <= MAX_EXP_ARGUMENT) then
r = exp(var)
else
exit do '// exit the loop
end if
'//use r
loop
do ....
There was a SO issue posted a while back dealing with numbers larger than Long in VBA.
The accepted answer pointed to a link called Large Number Arithmetic. I just tried to implement your example of exp(28000) using that example, but received a "Type Mismatch" error after processing a few loops. However, it may be the fault of my hasty implementation. If you've got no leads so far, I would start there.

Is there a reason to prefer a switch over an if statement with only one condition?

I found the following code in my team's project:
Public Shared Function isRemoteDisconnectMessage(ByRef m As Message)
isRemoteDisconnectMessage = False
Select Case (m.Msg)
Case WM_WTSSESSION_CHANGE
Select Case (m.WParam.ToInt32)
Case WTS_REMOTE_DISCONNECT
isRemoteDisconnectMessage = True
End Select
End Select
End Function
Never mind that the function doesn't have a return type (I can easily add 'As Boolean'); what I'm wondering is, could there be any reason to prefer the above over the following (to me, much more readable) code?
Public Shared Function isRemoteDisconnectMessage(ByRef m As Message) As Boolean
Return m.Msg = WM_WTSSESSION_CHANGE AndAlso _
m.WParam.ToInt32() = WTS_REMOTE_DISCONNECT
End Function
To put the question in general terms: Does it make sense to use a switch (or, in this case, Select Case) block--and/or nested blocks--to test a single condition? Is this possibly faster than a straightforward if?
If you're worried about performance...profile. Otherwise you can't go wrong erring on the side of readability...
I don't believe it actually matters in terms of speed, the compiler should be able to optimize it.
I think it would just be a matter of preference.
My rule of thumb is to use a switch statement when the number of if/else conditions is greater than three. I don't have any data behind why this makes sense other than readability/maintainability seems to decrease as the number of if/else conditions increases.
I think the answer in the specific case you've given is no - it doesn't make sense, as suggested in other answers one would hope that the compilers would optimise away any practical differences.
I'd put money on this being a bit of cut, paste and delete coding - taking a generalised set of nested case statements and extracting that one bit that gives you the yes/no result you need.
If this were something similar in-line and/or there was a function call where the return flag is set then one might, possibly, be at a point where one could start to justify it but not as it is.

Resources