3

I've recently upgraded Matlab from 2013b to 2019a (yes, I know, a lot has changed....but not software costs). I have some "legacy code" which makes heavy use of the symbolic tool box. One thing that seems to be causing a big issue is the change in notation. I think this question is best presented through example:

2013

>> F(x) = sym('F(x)');
>> subs(diff(F,x),x,1)

ans(x) =

D(F)(1)

2019

>> F(x) = str2sym('F(x)');
>> subs(diff(F,x),x,1)

ans(x) =

subs(diff(F(x), x), x, 1)

In 2019, F(x) = sym('F(x)'); would not work and I was told to switch to F(x) = str2sym('F(x)'); which seems to perform the operation as intended, but the notation is killing my code.

Is there a way to salvage the old notation or do I have to rewrite my code?

EDIT

Good comment.....how is this breaking my code? I use the symbolic tools to solve equations then parse them based on their structure. For example, if an expression has a third derivative, I would put that in group A. If it has a 7 derivative, I would put that in group B. In 2013, it was easy to parse for high derivatives...a third derivative would look like this D(D(D(F)))(x) in 2019 it looks like this diff(F(x), x, x, x). I've also found that 2019 mixes its notation. For example

F(x) = str2sym('F(x+dx)')
F(x) =

F(dx + x)

>> diff(F,x,3)

ans(x) =

D(D(D(F)))(dx + x)

At this point, I'm thinking this is just going to end up being one patch fix after another. Probably not the best idea to be parsing symbolic expressions if the notation is volatile. I was hoping there might be a "yeah, go to preferences and select..."

ThatsRightJack
  • 721
  • 6
  • 29
  • Why is it killing your code? Are you doing some parsing to string with it? Can you show the part where your code is broken, so we can know what to propose as solution – Ander Biguri Feb 18 '20 at 08:32
  • @AnderBiguri Yes...good guess. I updated the question, but I'm thinking this one is a dead end without some hack fix. I guess I shouldn't have done it that way to begin with. – ThatsRightJack Feb 18 '20 at 09:46
  • Well, one option would be to overload your parser to detect both cases. Maybe some regexp can fix the problem, or simply some simple checks. As long as those are the only possible cases (i.e. starting with `D(....` or starting with `diff(....`) then you can just make your symbolic parser more complex. If you could post it, maybe we can help. But in any case, yes, this will solve the problem now, just delaying its reappearance few years. Probably not the right way of solving this problem – Ander Biguri Feb 18 '20 at 09:52
  • Yeah, I'm now finding the problem only gets worse. After parsing, I would call other functions like `coeffs` , then do some vector operations, etc. The symbolic stuff seems to obey alphabetical(?) order in the output of such operations, so when expressions went from starting with `D` in 2013 to stating with `d` or `s` as in "diff" or "subs" in 2019 it messed up the order output. I built the original code not anticipating this. I can't just replace `diff` with `D` either because I actually evaluate the expression at some point. I would then need to parse it back. – ThatsRightJack Feb 18 '20 at 10:12
  • I would say that your best option is to sit down and make the time to update your code, and to try to find a different way of cracking the same problem.... – Ander Biguri Feb 18 '20 at 10:48
  • 1
    If adding something like the `+dx` makes 2019 switch notation to `D`, maybe you can just do something like that always and then substitute out the extra stuff? I don't have the symbolic toolbox so can't experiment, but just a thought. – bg2b Feb 18 '20 at 11:00
  • @AnderBiguri Yeah, that's what I'm currently doing. I think I should have thought it through a little better. Plus it gives me an excuse to revisit the good old TODO list. – ThatsRightJack Feb 18 '20 at 12:04
  • 1
    @bg2b Where were you 4 hours ago!! Just kidding but great idea. I actually just tested it with my example above. I changed `F(x) = str2sym('F(x)');` to this `F(x) = str2sym('F(x+dx)');` then by doing as you suggested `subs(diff(F,x),x + dx,1)` and sure enough it returns `D(F)(1)` which in my opinion is way easier to read then `subs(diff(F(x), x), x, 1)`. Write it up as an answer and I'll accept it – ThatsRightJack Feb 18 '20 at 12:16

2 Answers2

2

If adding something like the +dx makes 2019 switch notation to D, maybe you can just do something like that always and then substitute out the extra stuff? I don't have the symbolic toolbox so can't experiment, but just a thought.

Example

change F(x) = str2sym('F(x)'); to

F(x) = str2sym('F(x+dx)');

then use

subs(diff(F,x),x + dx,1)

which returns D(F)(1) and has the same meaning as subs(diff(F(x), x), x, 1)

ThatsRightJack
  • 721
  • 6
  • 29
bg2b
  • 1,939
  • 2
  • 11
  • 18
1

(requries MATLAB 2019a or later)

Not an answer on how to restore the old syntax, but to the problem you described. Here is how I would solve it:

%some example input
syms x f(x)
g=diff(f,x,3)+8
%find the expression with `diff` and get its arguments
a=children(findSymType(g,'diff'))

This will return [ f(x), x, x, x], which means all you have to do is to throw away the first element and count the x

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Daniel
  • 36,610
  • 3
  • 36
  • 69