Skip to content
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

implement as_numer_denom #731

Merged
merged 8 commits into from
Jan 8, 2016
Merged

Conversation

srajangarg
Copy link
Contributor

Working on adding as_numer_denom from SymPy

  • Add
  • Mul
  • Rational
  • Power
  • Complex
  • Think of more classes where as_numer_denom can be simplified

@srajangarg srajangarg changed the title implement as_numer_denom method [WIP] implement as_numer_denom Jan 1, 2016
@srajangarg srajangarg changed the title [WIP] implement as_numer_denom [ci skip] [WIP] implement as_numer_denom Jan 1, 2016
@srajangarg srajangarg changed the title [ci skip] [WIP] implement as_numer_denom [WIP] implement as_numer_denom Jan 1, 2016
@isuruf
Copy link
Member

isuruf commented Jan 1, 2016

@srajangarg take a look at one of the Visitor classes like EvalRealDoubleVisitor to see how to do this.

@srajangarg srajangarg force-pushed the as_numer_denom branch 2 times, most recently from 19c3b31 to 151452e Compare January 2, 2016 11:33
@srajangarg
Copy link
Contributor Author

@isuruf Does the structure look ok now?

@@ -47,5 +48,11 @@ RCP<const Basic> Basic::diff(const RCP<const Symbol> &x) const
return Derivative::create(rcp_from_this(), {x});
}

void Basic::as_numer_denom(const Ptr<RCP<const Basic>> &numer, const Ptr<RCP<const Basic>> &denom) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can move this to numer_denom.cpp

@srajangarg srajangarg mentioned this pull request Jan 2, 2016
3 tasks
REQUIRE(eq(*den, *one));

r1 = add(x, mul(y, pow(x, y)));
as_numer_denom(r1, outArg(num), outArg(den));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a test what the result in num and den is here.

@certik
Copy link
Contributor

certik commented Jan 3, 2016

@srajangarg I think this looks very good and clean. I left a small comment above.

namespace SymEngine {

// need a .h file to fix this
void as_numer_denom(const RCP<const Basic> &x, const Ptr<RCP<const Basic>> &numer, const Ptr<RCP<const Basic>> &denom);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can move this declaration to basic.h

@isuruf
Copy link
Member

isuruf commented Jan 3, 2016

One other class that you can be separated to numerator and denominator is Complex

@srajangarg srajangarg force-pushed the as_numer_denom branch 4 times, most recently from 5e70dac to 589ad4d Compare January 3, 2016 18:54
@srajangarg
Copy link
Contributor Author

@certik @isuruf
The PR adressing #681, seems to be complete from my side. Do you have any more ideas?

@@ -220,6 +220,7 @@ bool is_a_sub(const Basic &b);
RCP<const Basic> expand(const RCP<const Basic> &self);
umap_short_basic series(const RCP<const Basic> &ex, const RCP<const Symbol> &var, unsigned int prec);
umap_short_basic series_invfunc(const RCP<const Basic> &ex, const RCP<const Symbol> &var, unsigned int prec);
void as_numer_denom(const RCP<const Basic> &x, const Ptr<RCP<const Basic>> &numer, const Ptr<RCP<const Basic>> &denom);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move this into numer_denom.h? This algorithm doesn't need anything from the core, so I think it's cleaner if it lives separate from the core, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@isuruf suggested that I don't really need a .h file. I'm not the best judge as to what should be done, as I don't have the full vision of how the structure is to be built in the future. I'll stick to whatever you say.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just keep it as it is. We can always move things around later.

// if (eq(*divx_den, *one)) {
// curr_num = add(mul(arg_num, divx), curr_num);
// continue;
// } !! The below two 'general' statements cover this case
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the commented code be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should let it stay. Just explains what I've done. Always good, if changes are to be made in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the commented code is doing, or supposed to do. Is it a simplified version of the two lines below? It doesn't seem to assign to curr_den.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the case where the arg_den completely divides the curr_den (opposite of the previous case). Now as arg_den completely divides curr_den, curr_den doesn't have to be changed! After I check the two 'divide each other cases' I write the general version of 'multiplying denominators' (in an LCM sort of way) , by doing
curr_den = mul(curr_den, divx_den); and
curr_num = add(mul(curr_num, divx_den), mul(arg_num, divx_num));

We see that in the case commented out, divx_den was anyways going to be one and divx = divx_num, which would be anyways handled by the two lines (written above) and give the same result as expected.

curr_den = mul(curr_den, one); becomes curr_den = curr_den and
curr_num = add(mul(curr_num, one), mul(arg_num, divx)); becomes
curr_num = add(curr_num, mul(arg_num, divx));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see --- so the if statement is a special case, but it turns out that your general case already handles the special case. Is that right? Why don't you summarize what you just wrote in a small comment in the code to make this clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@certik
Copy link
Contributor

certik commented Jan 6, 2016

@srajangarg I think that this looks very good, I only left two minor comments/questions. Thanks for the work.

@certik certik changed the title [WIP] implement as_numer_denom implement as_numer_denom Jan 6, 2016
@certik
Copy link
Contributor

certik commented Jan 7, 2016

Thanks. I restarted the failing build on Travis.

@certik
Copy link
Contributor

certik commented Jan 7, 2016

That looks good to me and tests pass. @isuruf any other comments?

@Sumith1896
Copy link
Contributor

+1 from my side too

certik added a commit that referenced this pull request Jan 8, 2016
@certik certik merged commit 62a324b into symengine:master Jan 8, 2016
@certik
Copy link
Contributor

certik commented Jan 8, 2016

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants