-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sym() and vpa() refactor #804
Conversation
The double input part of the code no longer uses "const_to_python_str".
It does more than we need: we were only using it for the double conversion. Even there, it converted doubles-that-are-integers to strings which seems unncessary here.
It doesn't need to deal with doubles anymore
Fixes #799. This is for compatibility with SMT. I've slightly changed the heuristic: we return whichever choice minimizes the error.
This is not supposed to change anything
Remove the "check" flag by more agressively calling python_cmd as soon as we know its arguments instead of more complicated logic which tried to defer calling python_cmd.
Instead of using a flag, return empty or the new string. Document the private fcn a bit.
I guess this is mostly @latot's stuff: what do you think? Its probably hard to review overall but if you go commit-by-commit, I hope each one is sensible. |
y = python_cmd ('return -S.Pi'); | ||
elseif ((abs (x) < flintmax) && (mod (x, 1) == 0)) | ||
y = python_cmd ('return Integer(_ins[0])', int64 (x)); | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would like keep here some loop instead of check every var line by line....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think is more easy to handle, or maybe with less code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured you might say this ;-) I respect that point of view, but I disagree. To me a bunch if elseif
is readable and clear. Ultimately just a matter of style.
But if that list gets much longer in the future, then maybe I prefer your approach.
@@ -277,7 +277,6 @@ | |||
end | |||
|
|||
asm = {}; | |||
check = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to avoid the most possible call python_cmd every time, the main reason is #561, to can use classdef we will run an extra lines script every time we call that function for the limitations, so we can avoid write a lot of code and reduce it....
If you want remove it maybe instead keep it as comments? Just to don't loose the idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand. Is this about sym
explicitly calling itself? I thought we were not supposed to have the sym ctor explicitly calling sym(...)
, but it was ok if sym called some other function which then called sym(...)
.
What do you mean by "extra lines script every time we call that function for the limitations"? Can you give me an explicit bit of code that will need to change?
Sorry, but I've kind of lost track of the various classdef issues we face.
Does this comment need to be addressed before I merge this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would adding this comment address your concern?
% Note: a previous version of this code deferred most calls to `python_cmd
% until near the end of the function. Now, it is called in many places. Its
% possible this has some negative consequences for a future port to classdef.
% If you're reading this in the future and have successfully done that port,
% then please delete this comment ;-)
Otherwise, what should it say? (I don't understand what the issue is here so harder for me to make a precise statement).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if i remember right this was the reason https://savannah.gnu.org/bugs/?49421, in classdef we can't set properties, so every time when we try to set it we need to run the "Copy" function, other way maybe is store the result in a new var and set it in the end of the script, then we can call the function only one time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think I see, thank you.
There are paths in #590 that end early with s = meh...; return
, so I don't see this PR's code as being much worse. I will merge for now, fight with classdef when we get there ;-)
elseif (ischar(x)) | ||
x = magic_str_str(x); | ||
elseif (ischar (x)) | ||
if (strcmp (x, 'inf') || strcmp (x, 'Inf') || strcmp (x, '+inf') || ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, i maybe instead of this vpa we can simplify to:
function r = vpa(x, n)
if (nargin == 1)
n = digits();
elseif (nargin ~= 2)
print_usage ();
end
n = sym(n);
cmd = {
'x, n = _ins'
'return sympy.N(x, n),' };
r = python_cmd (cmd, x, n);
end
Actually pass all the tests, and seems works.
All the check we do here are basically what sym function does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, cool, I will think about this! Did you mean x = sym(x)
? Otherwise I don't see how that could work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i do something really bad when i test this, is necessary check this.
end | ||
else | ||
y = python_cmd ('return sqrt(Integer(*_ins))', int64 (N3)); | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking in the future, this is a great idea, to complement it i would like.. "split"? the differents methods to get the aproximation, so then we can get this file to be more easy to edit, i'm thinking to can add some "functions" and then the script run all in some loop and choose the best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that could be done in the future. Although I'm not sure there will be more heuristics: I read through the SMT docs and it sounds like these are the three cases they do.
else | ||
s = x; | ||
%% Rational will exactly convert from a float | ||
y = python_cmd ('return Rational(_ins[0])', x); | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inst/@sym/sym.m
Outdated
iscmplx = ~isreal (x); | ||
if (iscmplx && isequal (x, 1i)) | ||
s = python_cmd ('return S.ImaginaryUnit'); | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this part is related to the "check" comment.
Ready!, there is greats changes, there is the comments. |
I feel like I could tweak this forever, so here's some progress anyway. I've taken apart from of @latot's work to centralize
const_to_python_str
(which dealt with doubles and strings). That logic is a little more spread out now, but IMHO its clearly to understand@sym/sym
which is the code that matters.There were also sublte differences between what should happen with e.g.,
pi
insym(pi, 'f')
,sym(pi, 'r')
andvpa(pi)
.This also fixes a bug I introduces where
sym(inf, 'f')
was zero.`Finally, it fixes #604 by allowing
sym('i')
to make a variable namedi
rather than imaginary unit, which is for SMT compatibility.