Debugging a Complex TK ModelA customer sent me a TK model with 200+ lines on the variable sheet and 100+ lines on the rule sheet, plus several procedure functions called from the rules. The request was for help in getting the model to solve. When the iterative solver was launched, TK responded with the dreaded "Dependency Error" message.
That error indicates that when the iterative solver reached a certain point, it discovered that changes to one or more of the guess values no longer resulted in significant changes to the error terms it was trying to make zeros.
There are many different causes for this condition. The iterative solver may have started from poor guesses and diverged so far from the solution that the values have become extremely large. The error function may not be a smooth, continuous surface over a particular domain. There may not be a solution for the given set of inputs.
The key to diagnosing the problem is to overdefine the problem, changing the status of all the guess variables to inputs. (For this article, I will continue to refer to them as guess variables.) TK will detect an inconsistency and point to the offending rule. Edit in an error term. Repeat this process until you have new error variables associated with each of the guess variables. Make some changes to the guess variables and watch to see that the error terms update. It is sometimes useful to list solve using lists for each of the guess variables, one by one, as inputs and the error terms as outputs. In effect, this plots a slice of the solution hyperspace. What you're looking for is the sensitivity of each of the error terms to each of the guess variables. Also be on the lookout for ranges over which it appears an error doesn't seem to change. That would be a tar pit for the iterative solver if it stumbled into that range. In models with just a single guess variable, this plot will show you exactly where the solution lies.
Next, for models with two or more guess variables, make all but one of the error terms inputs of 0 and change the status of the associated guess variables to GUESS. The remaining error term should be an output and its associated guess variable should be an input. It may not be possible to get a solution under this scenario but if this works, it's a major breakthrough because now you can repeat the process over a range of values of the remaining guess variable to see where its associated error term becomes zero. In other words, get the model to where you can list solve over a single guess variable and you'll be able to get a plot of where that error term goes to zero.
In the case of the recent tech call, this process worked and unfortunately, it became clear that there was no feasible solution to the given problem. That is the error plot for the remaining variable never approached zero over the feasible range of inputs.
In some cases, the iterative solver requires extremely good guesses to find a solution and you might want to use the Optimizer as an alternative. The Optimizer is less reliant on the initial guesses and allows for adding bounds on the guess variables and constraints on related expressions. Assuming you have the error terms identified as described above, add a rule to the rule sheet to find the square root of the sum of the squared error terms. Then set up the Optimizer to minimize that value by changing the guess variable values within your desired bounds. If the Optimizer can't get the result down near 0, it's likely that there isn't a valid solution to the simultaneous equations.
In the case of the tech call model, the square root of the sum of squares of the three error terms was around 1000, so it wasn't even close.