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

[WIP] Wrappers for Real MPFR and Complex MPC #972

Merged
merged 9 commits into from
Jun 8, 2016
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions symengine/cwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <symengine/number.h>
#include <symengine/complex.h>
#include <symengine/complex_double.h>
#include <symengine/real_mpfr.h>
#include <symengine/complex_mpc.h>
#include <symengine/constants.h>
#include <symengine/visitor.h>
#include <symengine/printer.h>
Expand All @@ -32,6 +34,13 @@ using SymEngine::Number;
using SymEngine::Complex;
using SymEngine::ComplexDouble;
using SymEngine::RealDouble;
#ifdef HAVE_SYMENGINE_MPFR
using SymEngine::RealMPFR;
using SymEngine::mpfr_class;
#endif //HAVE_SYMENGINE_MPFR
#ifdef HAVE_SYMENGINE_MPC
using SymEngine::ComplexMPC;
Copy link
Member

Choose a reason for hiding this comment

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

Same here

#endif //HAVE_SYMENGINE_MPC
using SymEngine::rcp_static_cast;
using SymEngine::is_a;
using SymEngine::RCPBasicKeyLess;
Expand Down Expand Up @@ -200,6 +209,45 @@ double real_double_get_d(const basic s)
return (rcp_static_cast<const RealDouble>(s->m))->as_double();
}

#ifdef HAVE_SYMENGINE_MPFR

void real_mpfr_set_d(basic s, double d, int prec)
{
mpfr_class mc = mpfr_class(prec);
mpfr_set_d (mc.get_mpfr_t(), d, MPFR_RNDN);
s->m = SymEngine::real_mpfr(std::move(mc));
}

void real_mpfr_set_str(basic s, char *c, int prec)
{
s->m = SymEngine::real_mpfr(mpfr_class(c, prec, 10));
}

double real_mpfr_get_d(const basic s)
{
SYMENGINE_ASSERT(is_a<RealMPFR>(*(s->m)));
return mpfr_get_d ( ((rcp_static_cast<const RealMPFR>(s->m))->as_mpfr()).get_mpfr_t() , MPFR_RNDN);
}

void real_mpfr_set(basic s, mpfr_srcptr m)
{
s->m = SymEngine::real_mpfr(mpfr_class(m));
}

void real_mpfr_get(mpfr_ptr m, const basic s)
{
SYMENGINE_ASSERT(is_a<RealMPFR>(*(s->m)));
m = ((rcp_static_cast<const RealMPFR>(s->m))->as_mpfr()).get_mpfr_t();
Copy link
Member

Choose a reason for hiding this comment

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

Use mpfr_set here

}

mpfr_prec_t real_mpfr_get_prec(const basic s)
{
SYMENGINE_ASSERT(is_a<RealMPFR>(*(s->m)));
return ((rcp_static_cast<const RealMPFR>(s->m))->as_mpfr()).get_prec();
}

#endif // HAVE_SYMENGINE_MPFR

signed long integer_get_si(const basic s)
{
SYMENGINE_ASSERT(is_a<Integer>(*(s->m)));
Expand Down Expand Up @@ -410,6 +458,22 @@ int is_a_ComplexDouble(const basic c)
{
return is_a<ComplexDouble>(*(c->m));
}
int is_a_RealMPFR(const basic c)
{
#ifdef HAVE_SYMENGINE_MPFR
return is_a<RealMPFR>(*(c->m));
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 return false if HAVE_SYMENGINE_MPFR is not defined

#else
return false;
#endif // HAVE_SYMENGINE_MPFR
}
int is_a_ComplexMPC(const basic c)
{
#ifdef HAVE_SYMENGINE_MPC
return is_a<ComplexMPC>(*(c->m));
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 return false if HAVE_SYMENGINE_MPC is not defined. (Note: MPC not MPFR)

#else
return false;
Copy link
Member

Choose a reason for hiding this comment

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

Use an else here, otherwise the compiler spits out warnings about unreachable code

#endif // HAVE_SYMENGINE_MPC
}

// C wrapper for std::vector<int>

Expand Down
27 changes: 27 additions & 0 deletions symengine/cwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <stdlib.h>
#include <gmp.h>

#ifdef HAVE_SYMENGINE_MPFR
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 include symengine/symengine_config.h before this.

#include <mpfr.h>
#endif // HAVE_SYMENGINE_MPFR

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -129,6 +133,21 @@ void real_double_set_d(basic s, double d);
//! Returns double value of s.
double real_double_get_d(const basic s);

#ifdef HAVE_SYMENGINE_MPFR
//! Assign to s, a real mpfr that has value d with precision prec.
void real_mpfr_set_d(basic s, double d, int prec);
//! Assign to s, a real mpfr that has base 10 representation c with precision prec.
void real_mpfr_set_str(basic s, char *c, int prec);
//! Returns double value of s.
double real_mpfr_get_d(const basic s);
Copy link
Member

@isuruf isuruf Jun 3, 2016

Choose a reason for hiding this comment

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

For completeness, you'll need,

void real_mpfr_set(basic s, mpfr_srcptr m)
void real_mpfr_get(mpfr_ptr m, const basic s)
mpfr_prec_t real_mpfr_get_prec(const basic s)

//! Assign to s, a real mpfr that has value pointed by m.
void real_mpfr_set(basic s, mpfr_srcptr m);
//! Assign to m, the mpfr_t given in s.
void real_mpfr_get(mpfr_ptr m, const basic s);
//! Returns the precision of the mpfr_t given by s.
mpfr_prec_t real_mpfr_get_prec(const basic s);
#endif // HAVE_SYMENGINE_MPFR

//! Returns signed long value of s.
signed long integer_get_si(const basic s);
//! Returns unsigned long value of s.
Expand Down Expand Up @@ -264,6 +283,14 @@ int is_a_Rational(const basic s);
int is_a_Symbol(const basic s);
//! Return 1 if s is a Complex, 0 if not.
int is_a_Complex(const basic s);
//! Return 1 if s is a RealDouble, 0 if not.
int is_a_RealDouble(const basic c);
//! Return 1 if s is a ComplexDouble, 0 if not.
int is_a_ComplexDouble(const basic c);
//! Return 1 if s is a RealMPFR, 0 if not.
int is_a_RealMPFR(const basic c);
//! Return 1 if s is a ComplexMPC, 0 if not.
int is_a_ComplexMPC(const basic c);

//! Wrapper for std::vector<int>

Expand Down
2 changes: 1 addition & 1 deletion symengine/real_mpfr.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class mpfr_class
{
return mp;
}
explicit mpfr_class(mpfr_t m)
explicit mpfr_class(mpfr_srcptr m)
{
mpfr_init2(mp, mpfr_get_prec(m));
mpfr_set(mp, m, MPFR_RNDN);
Expand Down
39 changes: 39 additions & 0 deletions symengine/tests/cwrapper/test_cwrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include <symengine/cwrapper.h>
#include <string.h>

#ifdef HAVE_SYMENGINE_MPFR
#include <mpfr.h>
#endif // HAVE_SYMENGINE_MPFR

void test_cwrapper() {
char* s;
basic x, y, z;
Expand Down Expand Up @@ -196,6 +200,41 @@ void test_real_double()
basic_free_stack(d);
}

#ifdef HAVE_SYMENGINE_MPFR
void test_real_mpfr()
{
basic d;
basic_new_stack(d);
real_mpfr_set_d(d, 123.456, 200);
SYMENGINE_C_ASSERT(is_a_RealMPFR(d));
SYMENGINE_C_ASSERT(real_mpfr_get_d(d) == 123.456);
basic_free_stack(d);

char *s2 = "456.123";

basic e;
basic_new_stack(e);
real_mpfr_set_str(e, s2, 200);
SYMENGINE_C_ASSERT(is_a_RealMPFR(e));
SYMENGINE_C_ASSERT(real_mpfr_get_d(e) == 456.123);


mpfr_ptr mp;
real_mpfr_get(mp, e);

basic_new_stack(d);
real_mpfr_set(d, mp);
SYMENGINE_C_ASSERT(is_a_RealMPFR(d));
SYMENGINE_C_ASSERT(real_mpfr_get_d(d) == 456.123);

SYMENGINE_C_ASSERT(real_mpfr_get_prec(d) == 200);

basic_free_stack(d);
basic_free_stack(e);
basic_str_free(s2);
}
#endif // HAVE_SYMENGINE_MPFR

void test_CVectorInt1()
{
// Allocate on heap
Expand Down