Skip to content

Conversation

@rajithv
Copy link
Contributor

@rajithv rajithv commented May 12, 2016

No description provided.

VALUE result;

unsigned long cbasic_operand1;
cbasic_operand1 = NUM2ULONG(operand1);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@abinashmeher999 am I using this correctly? Pls check.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that is correct. If you get unsure about return types, refer here: http://rxr.whitequark.org/mri/ident

Copy link
Member

Choose a reason for hiding this comment

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

Then all you need to do is to add an implicit conversion of SymEngine::Integer into Integer

Copy link
Contributor Author

@rajithv rajithv May 13, 2016

Choose a reason for hiding this comment

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

I figured our half way on how to do this:

so I added a new method to the 'Integer' class
rb_define_method(c_integer, "to_int", cinteger_to_int, 0);

From which I should return a VALUE pointer pointing to a Ruby Bignum or a Fixnum. This can be done by converting a C int by using INT2NUM macro.

The step I'm stuck at is on extracting a C int from the SymEngine Integer object. @abinashmeher999 can you point me to somewhere I can read more about the Ruby Wrapper's SymEngine Integer's structure?

Copy link
Contributor

Choose a reason for hiding this comment

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

@rajithv, the Integer object uses GMP underneath. So you can extract a gmp int easily using the as_mpz() method. If you want an integer, you can call as_int(), but it will raise an exception if the integer doesn't fit into signed long int.

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 convert a SymEngine::Integer to a Ruby string first and then call to_i method

Copy link
Contributor

Choose a reason for hiding this comment

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

+1. This can be done. So instead of using the Ruby C API for the above, you can define #to_int in ruby itself here. Make a new file integer.rb and then proceed.

end

describe '#mod' do
context '5 mod 4' do
Copy link
Contributor

Choose a reason for hiding this comment

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

Also add tests for other permutations of a positive and a negative number and see if they behave the same way as ruby, because I have heard they do not behave the same way in python and C.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@abinashmeher999 The same happens in Ruby. So I should adapt the code to return Ruby-like answers. right?

Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO symengine's behavior should be consistent across all languages. But again there shouldn't be any surprises for ruby users. If both are same then it's good.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with the 2nd not the 1st point.
There are two versions, mod and mod_f and they are used in C++ and Python respectively. You want the mod_f version for Ruby

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 modified the ruby wrapper to return the same as mod_f.
But should I go ahead and wrap mod_f in SymEngine, and get that to the ruby wrapper? Or is it not necessary?

Also, should there be a way to access the c-style mod operation in Ruby?

Copy link
Member

Choose a reason for hiding this comment

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

It'll be better to have the mod_f function in SymEngine. For now, that's okay. You can open an issue to keep track of it.

@rajithv
Copy link
Contributor Author

rajithv commented May 13, 2016

@abinashmeher999 @isuruf good to merge?

@rajithv rajithv changed the title [WIP] Ruby Wrappers for NTheory Ruby Wrappers for NTheory May 13, 2016
#include "symengine_utils.h"

VALUE cntheory_onearg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*), VALUE operand1);
VALUE cntheory_twoarg(void (*cwfunc_ptr)(basic_struct*, const basic_struct*, const basic_struct*), VALUE operand1, VALUE operand2);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please break this one too.

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 actually not needed. Removed it.

@abinashmeher999
Copy link
Contributor

Let's wait for the tests to pass.

describe '#mod' do
context '5 mod 4' do
it 'returns 1' do
f = SymEngine::mod(5, 4)
Copy link
Member

Choose a reason for hiding this comment

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

This should use ruby's % operator

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I should overload % right? not introduce a new method as mod.

Copy link
Member

Choose a reason for hiding this comment

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

Yes.

context '5 mod 4' do
it 'returns 1' do
f = SymEngine::mod(5, 4)
f = 5 % 4
Copy link
Member

Choose a reason for hiding this comment

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

You are testing ruby's in built ints here

@rajithv
Copy link
Contributor Author

rajithv commented May 17, 2016

@abinashmeher999 @isuruf pls review.

describe '#fibonacci' do
context '5th Fibonacci Number' do
it 'returns 5' do
f = SymEngine::fibonacci(5)
Copy link
Member

Choose a reason for hiding this comment

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

You should add another test which uses a SymEngine integer instead of Ruby's

Copy link
Contributor

Choose a reason for hiding this comment

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

Better to add it to all of them. Or at least one for one argument and one for two argument function.

@rajithv
Copy link
Contributor Author

rajithv commented May 17, 2016

@isuruf @abinashmeher999 done

context '-5 mod 4' do
it 'returns 3' do
f = @im5 % @i4
expect(f).to eql(3)
Copy link
Contributor

Choose a reason for hiding this comment

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

So, f is a SymEngine::Integer, right? Will implicit conversion happen here while comparing?

Copy link
Contributor

@abinashmeher999 abinashmeher999 May 17, 2016

Choose a reason for hiding this comment

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

expect(f).to eql(5)
end
end
context 'binomial (n=5, k=1)' do
Copy link
Contributor

Choose a reason for hiding this comment

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

Make the wording of the context like with SymEngine::Integer as parameters and same for the test above this with ruby Integer as parameters. This is easier to read when tests are run in verbose mode. Currently it will print

#binomial
    binomial (n=5, k=1)
        returns 5
    binomial (n=5, k=1)
        returns 5

Accordingly modify it string. If the tests pass please make sure to make these changes in a new PR.

@abinashmeher999
Copy link
Contributor

@rajithv Thanks for the PR and your patience. +1 to merge. The minor changes can be incorporated in another PR.

@isuruf isuruf merged commit 7ea8a63 into symengine:master May 17, 2016
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.

4 participants