The code contains an expression too complex for code analysis to handle
Show older comments
I’m working on a modified SEIR model that has a couple of states. However, each state is partitioned into many compartment. Hence, the number of terms in each differential equation becomes very large. I tried to use MATLAB ode23s to solve the differential equations and got the following warning, “The file is too complex to analyze. The code contains an expression too complex for code analysis to handle.”
One of the equations is like this.
dS1 = - S1*phi1*I1 - S1*phi2*I2 - S1*phi3*I3 - … - S1*phi144*I144 - S1*alpha1*P1 - S1*alpha2*P2 - S1*alpha3*P3 … - S1*alpha144*P144 - S1*theta1*E1 - S1*theta2*E2 - S1*theta3*E3 … - S1*theta144*E144;
That’s a total of 432 terms. The warning/error appears once the number of terms in the equation exceed 144.
Is there a limit to number of terms in a differential equation that can be solve using MATLAB? Any suggestion on how I can handle this problem?
Thanks in advance.
9 Comments
This doesn't look like 432 variable, but much fewer:
dS1= -S*phi*I -S*alpha*P -S*theta*E;
Where some of these are vectors.
I don't have any meaningful experience with ode, but you might want to try to reduce your definition to vectorized code instead of numbered variables.
Walter Roberson
on 4 Aug 2021
That problem can occur on very long lines.
It is often not so much the line length that is the issue, but rather the number of levels of brackets simultaneously open.
The cure is to break the line into smaller pieces.
The problem does not have anything to do with the number of elements in a vector or matrix: it only has to do with how long the lines are.
OgaEngr
on 4 Aug 2021
Bjorn Gustavsson
on 4 Aug 2021
Before you continue with that editing work, use the vector-matrix capabilities of matlab first to rewrite your ODE-system using cleaner vector-matrix-operations. That will be way way more easy to maintain, analyse and most likely more efficient as well.
Rik
on 4 Aug 2021
It also probably isn't the solution. I would expect the parser to merge that back to 1 line.
If you really want to split into smaller pieces I would expect you would need this:
dS1_1 = -A -B -C -D;
dS1_2 = -E -F -G -H;
dS1_3 = -I -J -K -L;
dS1=dS1_1+dS1_2+dS1_3;
But, again, use arrays instead of numbered variables.
Walter Roberson
on 4 Aug 2021
When you use ... then the exact behavior depends upon your release.
Until recently, the behavior was that starting from the first dot to the end of the line was deleted, and the next line was brought in and concatenated on the end starting from the position the first dot was in. So for example,
A = B + C...
D
would have been converted into
A = B + CD
The resulting line would be scanned, dots on it would lead to the same behavior, and so on.
A small number of releases ago, the behaviour was changed so that instead of ... to the beginning of the next line just being deleted, that a space would be substituted. So the case above would be converted to
A = B + C D
You can see from this that using ... does not reduce the complexity of lines for machine parsing purposes -- but it can certainly make code easier for humans to read!
What Rik shows, creating different variables that each handle part of the calculation, is the approach needed to reduce parsing complexity.
Walter Roberson
on 4 Aug 2021
But, again, use arrays instead of numbered variables.
Speaking for myself: when I am breaking a long expression into lines, I am likely to use numbered parts, such as converting a series of additions of complicated terms into something like
part1a = some term;
part1b = some other term;
part1 = exp(part1a./part1b);
stuff
dS1 = part1 + part2 + part3;
Using arrays instead of numbered terms would require that I figure out what the possible expression sizes are at each point, and make sure to store along an appropriate dimension (taking efficiency into account). I do not think that is worth the effort. ideally each of the "part" variable names would be replaced with a meaningful name such as AgS04_disassociation_rate rather than even using arrays (because array indices are less informative than names), but a lot of the time I am doing my job of getting code working and going back to textbooks to figure out what each subexpression means is just not worth the trouble. Coding things like part1a is good enough a lot of the time. If a domain knowledge specialist wants to go back and assign meaningful names then they can take my working code adapatation to do so.
Working (especially debugged) code is priority #1 a lot of the time in STEM applications. There certainly are situations where code style is important, such as large team projects that are expected to survive for extended periods, but working slow / less-pretty code beats non-working faster / prettier code except when time constraints are part of the specification. Working code that uses numbered variables like part1b can be used as a reference results to ensure that proposed prettier / faster code gets the right result.
Rik
on 4 Aug 2021
You should only use single letter/numbered variables when it is obvious what they mean. What is obvious depends on context. The example you give is probably fine (since it should be clear that it is a single calculation broken into parts (that may or may not have meaning) to reduce typos and parsing complexity). However, using 300+ number variables is probably not the way to go. It doesn't make sense to assume there aren't any typos in such an expression without it being generated by some code. And if it is generated I don't really see why it couldn't have been generated as an array instead.
I'm not saying a swiss army knife shouldn't ever be used. I'm just saying you should consider other tools if you have a block of marble you want to sculpt.
But I suspect we mostly agree and that we're arguing over nuaces here.
Bjorn Gustavsson
on 4 Aug 2021
dS1 = - S1*( phi_all(:).'*I_all(:) + alpha(:).'*P_all(:) + theta_all(:).'*E_all(:) );
Answers (0)
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!