Skip to content

Conversation

@abinashmeher999
Copy link
Contributor

@rajithv Please open up a WIP PR from now on whenever you start working on something. That way if you run into a problem, all the conversations can happen there.

imag = rb_funcall(comp_value, rb_intern("imaginary"), 0, NULL);

crational_init(real_basic, real);
crational_init(imag_basic, imag);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

crational_init takes a VALUE and extracts the c pointer from that in this line. You are passing a basic_struct * which is being cast to VALUE/unintptr_t/void *.

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 assume you want to extract the numerator and denominator info from ruby Rational objects so that you can pass it to complex_set. You can use sympify to do that.

Copy link
Contributor

Choose a reason for hiding this comment

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

@abinashmeher999 I realised that this is wrong and am looking to solve the issue with sympify. This would solve the issue with Rational as well.

@rajithv
Copy link
Contributor

rajithv commented May 24, 2016

@abinashmeher999 @isuruf

The sympify function has been exposed, but there's a small error. I am guessing it's a result of mismanaging memory, but cannot seem to find out what's causing the error. Probably something small. I've been trying for a long time now, without success.

Basically, this is what happens now:

2.1.8 :002 > a = Rational('1/2')
 => (1/2) 
2.1.8 :003 > a1 = SymEngine::sympify(a)
 => #<SymEngine::Rational:0x92831c0> 
2.1.8 :004 > a1.class
 => SymEngine::Rational 
2.1.8 :005 > a1.to_s
(irb):5: [BUG] Segmentation fault at 0x000001
ruby 2.1.8p440 (2015-12-16 revision 53160) [i686-linux]

and

2.1.8 :001 > a = 100
 => 100 
2.1.8 :002 > b = 200
 => 200 
2.1.8 :005 > a1 = SymEngine::sympify(a)
 => #<SymEngine::Integer:0x8a8f374> 
2.1.8 :006 > b1 = SymEngine::sympify(b)
 => #<SymEngine::Integer:0x8a83fd8> 
2.1.8 :007 > c1 = a1 + b1
terminate called after throwing an instance of 'std::logic_error'
  what():  /home/rajith/Development/symengine/symengine/utilities/teuchos/Teuchos_RCPNode.hpp:95:

Throw number = 1

Throw test that evaluated to true: true

Any insights into solving this issue?


VALUE result;
basic cbasic_operand;
basic_new_stack(cbasic_operand);
Copy link
Member

Choose a reason for hiding this comment

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

basic_new_stack -> basic_new_heap

Copy link
Contributor

Choose a reason for hiding this comment

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

it did not work.. actually now the error comes earlier

2.1.8 :002 > a = Rational('1/2')
 => (1/2) 
2.1.8 :003 > a1 = SymEngine::sympify(a)
terminate called after throwing an instance of 'std::logic_error'
  what():  /home/rajith/Development/symengine/symengine/utilities/teuchos/Teuchos_RCPNode.hpp:95:

Copy link
Contributor

Choose a reason for hiding this comment

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

@isuruf thanks. It's working now.

sympify(real, real_basic);
sympify(imag, imag_basic);

complex_set(cbasic_operand2, real_basic, imag_basic);
Copy link
Member

Choose a reason for hiding this comment

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

complex_set requires integers or rationals, but Ruby complex can have any real number as real and imaginary parts.
Best way is to do cbasic_operand2 = real_basic + basic_const_I * imag_basic

@rajithv
Copy link
Contributor

rajithv commented May 25, 2016

@abinashmeher999 @isuruf

Shall we do the Complex Doubles and Complex MPCs in another PR? I am looking into complex doubles now, and it will need wrapping real values into Ruby as well. So I will add more tests for the SymEngine::Complex here, and then move on to another PR.

If there is anything else that needs to be done here, let me know.



basic_struct *const_I = basic_new_heap();
basic_struct *imag_part = basic_new_heap();
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 use cbasic_operand2 instead of the new variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1

@abinashmeher999
Copy link
Contributor Author

We will also need a #to_c method for implicit conversion to Complex. Shouldn't take long.

it 'returns an instance of SymEngine::Integer class' do
a = Complex(2, 7)
a = SymEngine::S(a)
a = a.real
Copy link

Choose a reason for hiding this comment

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

It's bad practice to re-assign variables in side a single unit test. r = a.real would be better.

@v0dro
Copy link

v0dro commented May 27, 2016

One thing that I notice is that you're following 4 space tabs everywhere. Is that a convention for symengine in general? In Ruby we generally use a 2 space tab.

@rajithv
Copy link
Contributor

rajithv commented May 27, 2016

I have been following the same convention as per the existing repository. But generally in the repo the Ruby files have a 2 space tab. And C files have a 4 space tab. Maybe @abinashmeher999 and @isuruf can give more detailed answers on these.

describe '#i' do
subject(:i) { SymEngine::I }

it { is_expected.to be_a SymEngine::Constant }
Copy link
Member

Choose a reason for hiding this comment

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

Is this passing? I is not a constant, it's a Complex

@rajithv
Copy link
Contributor

rajithv commented May 28, 2016

@abinashmeher999 @isuruf please review

module SymEngine
class Complex
def to_c
self.to_s.sub('I', 'i').sub('*','').gsub(' ','').to_c
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • unnecessary self;
  • tr is better than sub in this case: tr('I', 'i').tr('* ', '')


basic_free_stack(cbasic_operand);

return result;
Copy link
Member

Choose a reason for hiding this comment

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

Use function_onearg instead of the above implementation.

@isuruf
Copy link
Member

isuruf commented May 28, 2016

+1 to merge, @zverok, any other comments?

module SymEngine
class Complex
def to_c
to_s.tr('I', 'i').tr('*','').tr(' ','').to_c
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is pretty minor, but you can use one tr('* ', '') instead of two, when replacing chars with nothing.
Oh! Last moment thought: just String#delete would be even better :)

@zverok
Copy link
Collaborator

zverok commented May 28, 2016

Only one last (and pretty minor). Otherwise everything looks good to me 👍

@rajithv
Copy link
Contributor

rajithv commented May 28, 2016

Thanks for the insight @zverok

@isuruf isuruf changed the title [WIP] Complex class Complex class May 29, 2016
@isuruf isuruf merged commit 6d9b596 into symengine:master May 29, 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.

6 participants