Last update March 7, 2012

Dwith Swig / Examples /
Qdmath



Difference (last change) (no other diffs, normal page display)

Deleted: 271,381d270
jam tangan
jam tangan murah
jam tangan kw
hostgator coupon
kata mutiara
Jasa SEO
EZido
RDAnet
pioneer deh-1300mp
asus a53e-xa2
asus tf101-b1
asus tf101-a1
asus n53sv-eh72
asus republic of gamers g74sx
asus acer a5250
acer chromebook ac700
asus asus 53u
lg infinia 55lw5600
Sonicview 360 premier
asus 7 cu ft freezer
asus 30 single wall oven
brother cs6000i sewing machine
brother 1034d serger
brother sewing machines
Yokohama Geolandar H/T-S
crib tent tots in mind
kidco peapod plus
foscam fi8910w
samsung pl120 review
gopro helmet cam
Canon SX130IS
powershot s100
ContourHD 1080p
canon vixia hf r21
digital picture frame
canon ef 50mm f1.4
canon ef 70-300mm review
wide angle lenses
moving comfort sports bra
moving comfort bra
womens argyle sweater
bebe dresses
ViewSonic VX2250WM
Le Pan TC 970
Apple MacBook Air MC965LL
Sennheiser CX 880
plantronics cs540
ultrasonic jewelry cleaner
Sennheiser RS120
bose quietcomfort 15 acoustic noise cancelling headphones
logitech harmony one remote
logitech harmony 900
sony mhc-ec69i
sony mhcec909ip
bose wave music system
sony htss380
logitech squeezebox touch
sony dvp-fx970
onkyo tx-nr509
onkyo tx - nr609
onkyo ht-s3400
energy 5.1 take classic home theater system
polk audio psw505
onkyo ht-s5400
onkyo tx-nr709
belkin pf60
onkyo ht-rc360
denon avr-1912
Yamaha YHT-S400BL
fujitsu scansnap s1500
brother hl-2270dw
epson workforce 545
hp laserjet p2055dn
bushnell 8mp trophy cam
toshiba 32c110u
panasonic viera tc-p60s30
VIZIO E220VA
hauppauge wintv dcr-2650
Acer AM3970-U5022
Acer AspireRevo AR3700-U3002
Dell Inspiron i570
Dell GX620
Gateway FX6860-UR20P
Western Digital My Passport Essential SE 1 TB USB 3.0
Fujitsu ScanSnap S1300
Epson Perfection V300
Fujitsu SCANSNAP S1100
NeatDesk Desktop Scanner and Digital Filing System
Epson WorkForce Pro GT-S50
Kodak P811BK
Epson Perfection V330
Viewsonic VX2453MH
Asus VE228H
ViewSonic VA2431WM
Samsung B2230
HP 2711x
ASUS ML228H
Epson PowerLite Home Cinema 8350
Optoma PK301
Epson EX7210
Epson EX5210
ViewSonic PJD5133
Acer X1161P
FAVI RioHD-LED-2
Epson EX3210
ViewSonic PJD6531w
Trinity 360 Breville 800JEXL
Skil 3320-02
Delta 46-460
Grizzly G0555
Delta 18-900L

Table of contents of this page
C++ classes for extended precision   
Features used   
Code to be wrapped   
Interface file   
Run SWIG   
Example Application   
Compile and Link   
Output   

C++ classes for extended precision    

This example wraps a set of C++ classes called qd for double double and quadruple double precision calculations. For details of this code please see the work of Yozo Hida. This code is based on qd-2.1.56.

Features used    

There are a number of features used here which have not appeared in the other examples. These are all used in the interface for qd

  • wrapping of pointers by SWIG
Some of the functions to be wrapped have as an argument a pointer to uint. This is wrapped by SWIG as SWIGTYPE_p_uint which it regards as an object to be passed through. In the wrapping this generates a class of the same name which is defined in a file called classSWIGTYPE_p_uint.d.

  • pragma for module level statements
Functions in the interface file which are not contained in a class will be wrapped as D functions defined in the module file. This file needs to have import statements for the classes used by the functions, and these are inserted using a pragma command e.g.

%pragma(dmd) moduleimports="import classqd_real;
import classSWIGTYPE_p_uint;
"

  • extend command to add functionality to the class in the target language
The SWIG extend command allows member functions to be defined in the target class in the D language which are not in the C++ class. This is used here for overloaded operators and also to define an output function.

  • overloaded operators to allow use of operators in the target language
Examples are given of overloading of arithmetic operators to permit these operators to be used in D.

Code to be wrapped    

The code to be wrapped is contained in a series of header files and a library. It must be installed before SWIG can be used. I have used only the version for Linux.

Interface file    

// qd.i SWIG interface for qd package
// developed for the version qd-2.1.56 by Yozo Hida
// from http://www.cs.berkeley.edu/~yozo/

%module qdmath

%{
#define X86
#include <qd/qd.h>
#include <qd/fpu.h>
#include <stdio.h>
#include <sstream>
using namespace std;
%}

%pragma(dmd) moduleimports="import classqd_real;
import classSWIGTYPE_p_uint;
"
%rename(qd_sqrt) sqrt;
qd_real sqrt(const qd_real &a);
%rename(dd_sqrt) sqrt;
dd_real sqrt(const dd_real &a);
%rename (qd_fpu_fix_start) fpu_fix_start;
void fpu_fix_start(uint *old_cw);
%rename (qd_fpu_fix_end) fpu_fix_end;
void fpu_fix_end(uint *old_cw);

%pragma(dmd) classimports="import classdd_real;"

class qd_real {
public:
  qd_real();
  qd_real(const char *s);
  qd_real(const qd_real &dd);
  qd_real(const dd_real &dd);
  qd_real(double d);
  qd_real(int i);
  %rename(value) operator double;
  operator double();
  %rename(dd_value) operator dd_real;
  operator dd_real();
%extend {
   %rename(opAdd) operator+;
   qd_real operator +(const qd_real &c)
   {
       return *self + c;
   }
   %rename(opSub) operator-;
   qd_real operator -(const qd_real &c)
   {
       return *self - c;
   }
   %rename(opMul) operator*;
   qd_real operator *(const qd_real &c)
   {
       return *self * c;
   }
   %rename(opDiv) operator/;
   qd_real operator /(const qd_real &c)
   {
       return *self / c;
   }
   char* str() {
/* Note that as from gcc 3.2 this needs the <sstream> header. */
/* Note also the cast on the return needed to fool gcc 3.2 */
       std::ostringstream out;
       out << *self;
       return (char *) out.str().c_str();
   }
  };
};

%pragma(dmd) classimports="import classqd_real;"

class dd_real {
public:
  dd_real();
  dd_real(const char *s);
  dd_real(const dd_real &dd);
  dd_real(double d);
  dd_real(int i);
  %rename(value) operator double;
  operator double();
%extend {
   %rename(opAdd) operator+;
   dd_real operator +(const dd_real &c)
   {
       return *self + c;
   }
   %rename(opSub) operator-;
   dd_real operator -(const dd_real &c)
   {
       return *self - c;
   }
   %rename(opMul) operator*;
   dd_real operator *(const dd_real &c)
   {
       return *self * c;
   }
   %rename(opDiv) operator/;
   dd_real operator /(const dd_real &c)
   {
       return *self / c;
   }
   char* str() {
/* Note that as from gcc 3.2 this needs the <sstream> header. */
/* Note also the cast on the return needed to fool gcc 3.2 */
       std::ostringstream out;
       out << *self;
       return (char *) out.str().c_str();
   }
  };
};

Run SWIG    

swig -dmd -c++ qd.i

The output is the following files

  • qdmath.d
  • classdd_real.d
  • classqd_real.d
  • classSWIGTYPE_p_uint.d
  • qdmathPINVOKE.d
  • qd_wrap.cxx

Example Application    

runqd.d demonstrates the precision by computing the square root of two with different types.

// Experiments  with D reals and doubles.

// Imports conversion stuff from C
import std.string;
import std.intrinsic;
import std.math;
import classSWIGTYPE_p_uint;
import qdmath;
import classqd_real;
//import classdd_real;

int main(char[][] args)
{
    printf("Compute the square root of two to different precision\n");
    printf("In each case square the result and subtract two\n");
    double d = 2.;
    double d2 = sqrt(d);
    printf("double d = %lf, d2 = sqrt(d) = %lf, d2*d2-d = %le\n",d, d2, d2*d2-d);
    real r = 2.;
    real r2 = sqrt(r);
    printf("real r = %Lf, r2 = sqrt(r) = %Lf, r2*r2-r = %Le\n",r, r2, r2*r2-r);

// fpu fixup needed for qd
    SWIGTYPE_p_uint u;
    qd_fpu_fix_start(u);

    dd_real dd2 = new dd_real(2.);
    printf("dd2 = %s\n",dd2.str());
    dd_real dds = dd_sqrt(dd2);
    printf("dds = qd_sqrt(dd2) =\n%s\n",dds.str());
    dd_real ddx = dds*dds - dd2;
    printf("ddx = dds*dds - dd2 = \n%s\n",ddx.str());

    qd_real qd2 = new qd_real(2.);
    printf("qd2 = %s\n",qd2.str());
    qd_real qds = qd_sqrt(qd2);
    printf("qds = qd_sqrt(qd2) =\n%s\n",qds.str());
    qd_real qdx = qds*qds - qd2;
    printf("qdx = qds*qds - qd2 = \n%s\n",qdx.str());

    printf("A little simple arithmetic\n");
    qd_real qd1 = new qd_real(1.);
    printf("qd1 = %s\n",qd1.str());
    qd_real qd3;
    qd3 = qd1 + qd2;
    printf("qd3 = qd1 + qd2 = \n%s\n",qd3.str());

    qd_fpu_fix_end(u);
    printf("End of tests\n");
    return 0;
}

Compile and Link    

Linux

dmd -c runqd.d
dmd -c qdmath.d
dmd -c classdd_real.d
dmd -c classqd_real.d
dmd -c classSWIGTYPE_p_uint.d
g++ -c qd_wrap.cxx
g++ runqd.o -orunqd qdmath.o classdd_real.o classqd_real.o classSWIGTYPE_p_uint.o qd_wrap.o -lqd -lphobos -lpthread -lm

Note use of library -lqd.

Windows

I have not done this. There is a windows version of qd.

Output    

Compute the square root of two to different precision
In each case square the result and subtract two
double d = 2.000000, d2 = sqrt(d) = 1.414214, d2*d2-d = 2.734358e-16
real r = 2.000000, r2 = sqrt(r) = 1.414214, r2*r2-r = -1.084202e-19
dd2 = 2.0000000000000000000000000000000E0
dds = qd_sqrt(dd2) =
1.4142135623730950488016887242097E0
ddx = dds*dds - dd2 =
-9.8607613152626475676466070660350E-32
qd2 = 2.000000000000000000000000000000000000000000000000000000000000000E0
qds = qd_sqrt(qd2) =
1.414213562373095048801688724209698078569671875376948073176679738E0
qdx = qds*qds - qd2 =
1.519290839321567799595718763129913144675354533379191194604764799E-64
A little simple arithmetic
qd1 = 1.000000000000000000000000000000000000000000000000000000000000000E0
qd3 = qd1 + qd2 =
3.000000000000000000000000000000000000000000000000000000000000000E0
End of tests


FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: March 7, 2012 20:27 (diff))