Structures for passing information
Complex numbers are usually represented as a+bi where a and b are real numbers. a is called the real part and bi the imaginary part. We implement the following C structure to store a complex number:
typedef struct { int refcnt; /* For reference count */ double re, im; /* Real and imaginary parts */ } s_complex;
List of subroutines
The main interest of this example lies in the definition of its list of subroutines which actually is a list of operators:
static XPRMdsofct tabfct[]= { {"@&", 1000, XPRM_TYP_EXTN, 1, "complex:|complex|", cx_new0}, {"@&", 1001, XPRM_TYP_EXTN, 1, "complex:r", cx_new1}, {"@&", 1002, XPRM_TYP_EXTN, 2, "complex:rr", cx_new2}, {"@0", 1003, XPRM_TYP_EXTN, 0, "complex:", cx_zero}, {"@1", 1004, XPRM_TYP_EXTN, 0, "complex:", cx_one}, {"@:", 1005, XPRM_TYP_NOT, 2, "|complex||complex|", cx_asgn}, {"@:", 1006, XPRM_TYP_NOT, 2, "|complex|r", cx_asgn_r}, {"@+", 1007, XPRM_TYP_EXTN, 2, "complex:|complex||complex|", cx_pls}, {"@+", 1008, XPRM_TYP_EXTN, 2, "complex:|complex|r", cx_pls_r}, {"@*", 1009, XPRM_TYP_EXTN, 2, "complex:|complex||complex|", cx_mul}, {"@*", 1010, XPRM_TYP_EXTN, 2, "complex:|complex|r", cx_mul_r}, {"@-", 1011, XPRM_TYP_EXTN, 1, "complex:|complex|", cx_neg}, {"@/", 1012, XPRM_TYP_EXTN, 2, "complex:|complex||complex|", cx_div}, {"@/", 1013, XPRM_TYP_EXTN, 2, "complex:|complex|r", cx_div_r1}, {"@/", 1014, XPRM_TYP_EXTN, 2, "complex:r|complex|", cx_div_r2}, {"@=", 1015, XPRM_TYP_BOOL, 2, "|complex||complex|", cx_eql}, {"@=", 1016, XPRM_TYP_BOOL, 2, "|complex|r", cx_eql_r} };
In the order of their appearance this list defines the following operators:
- @&
- creation (construction)
- @0
- zero element for sums
- @1
- one element for products
- @:
- assignment
- @+
- addition
- @*
- multiplication
- @-
- negation
- @/
- division
- @=
- comparison (test of equality)
For most operators in the list above several versions are defined, with different types or combinations of types. The only type conversion that is carried out automatically by Mosel is from integer to real (but not the other way round), and no conversions involving external types. It is therefore necessary to define all the operations between two numbers for two complex numbers and also for a complex and a real number. For commutative operations (addition, multiplication, comparison) it is only required to define one version combining the two types, the other sense is deduced by Mosel: for example, if complex + real is defined, Mosel `knows' how to calculate real + complex. For division (not commutative) we need to define every case separately.
List of types
The definition of the new type in the list of types that is passed to Mosel looks as follows:
static XPRMdsotyp tabtyp[]= { {"complex", 1, XPRM_DTYP_PNCTX|XPRM_DTYP_RFCNT|XPRM_DTYP_APPND, cx_create, cx_delete, cx_tostr, cx_fromstr, cx_copy, cx_compare} };
The type-related functions (cx_create: creation, cx_delete: deletion, cx_tostr: transformation to a string, cx_fromstr: initialization from a string, cx_copy: copying, cx_compare: comparison) could be implemented in a similar way to what has been shown for the task module in the previous chapters. But, for practical purposes, this rudimentary memory management may not be efficient enough. In this chapter we therefore give an example of improved memory management for external types. This includes new versions of the type instance creation and deletion functions, an adaptation of the reset service, and the definition of additional list structures for storing information in the module context.
The functions for converting types to or from strings and also the copy and compare functions described for the task module only require minor modifications to adapt them to this example. Their definition will not be repeated in this chapter.
The list of services (merely consisting of the reset service) and the main interface structure are also very similar to those of the task module, and the module initialization function remains the same except for its name. We therefore refrain from printing them here.
The complete source code of the complex module is among the module examples provided with the Mosel distribution and on the Xpress website.