Definition of operators
In this section we show several examples of the implementation of operators. A comprehensive list of all operators that may be defined in Mosel is given in the appendix.
Constructors
In the chapter about the task module we have already seen examples of functions for cloning a new type and constructing it in different ways. Here the cloning operation is implemented as follows:
static int cx_new0(XPRMcontext ctx, void *libctx) { s_complex *complex,*new_complex; complex=XPRM_POP_REF(ctx); if(complex!=NULL) { new_complex=cx_create(ctx, libctx, NULL, 0); *new_complex=*complex; XPRM_PUSH_REF(ctx, new_complex); } else XPRM_PUSH_REF(ctx, NULL); return XPRM_RT_OK; }
A new complex number is constructed from two given real numbers thus:
static int cx_new2(XPRMcontext ctx, void *libctx) { s_complex *complex; complex=cx_create(ctx, libctx, NULL, 0); complex->re=XPRM_POP_REAL(ctx); complex->im=XPRM_POP_REAL(ctx); XPRM_PUSH_REF(ctx, complex); return XPRM_RT_OK; }
Comparison operators
Another operation that we have already seen in the task module is the comparison between new types. This can be done in a very similar way for module complex and is not repeated here. In addition, it makes sense to define a comparison between a complex and a real number:
static int cx_eql_r(XPRMcontext ctx,void *libctx) { s_complex *c1; double r; int b; c1=XPRM_POP_REF(ctx); r=XPRM_POP_REAL(ctx); if(c1!=NULL) b=(c1->im==0)&&(c1->re==r); else b=(r==0); XPRM_PUSH_INT(ctx,b); return XPRM_RT_OK; }
Arithmetic operators
The arithmetic operations must implement the rules to perform these operations on complex numbers.
Multiplication
Taking the example of the multiplication, we have to define the multiplication of two complex numbers: (a+bi) · (c+di) = ac - bd + (ad+bc)i
static int cx_mul(XPRMcontext ctx, void *libctx) { s_complex *c1,*c2; double re,im; c1=XPRM_POP_REF(ctx); c2=XPRM_POP_REF(ctx); if(c1!=NULL) { if(c2!=NULL) { re=c1->re*c2->re-c1->im*c2->im; im=c1->re*c2->im+c1->im*c2->re; c1->re=re; c1->im=im; } else c1->re=c2->im=0; } cx_delete(ctx, libctx, c2, 0); XPRM_PUSH_REF(ctx, c1); return XPRM_RT_OK; }
and also the multiplication of a complex with a real: (a+bi) · r = ar + bri
static int cx_mul_r(XPRMcontext ctx, void *libctx) { s_complex *c1; double r; c1=XPRM_POP_REF(ctx); r=XPRM_POP_REAL(ctx); if(c1!=NULL) { c1->re*=r; c1->im*=r; } XPRM_PUSH_REF(ctx, c1); return XPRM_RT_OK; }
It is not necessary to define the multiplication of a real with a complex since this operation is commutative and Mosel therefore deduces this case.
Addition, subtraction, division
The addition of two complex numbers and of a complex and a real number is implemented in a very similar way to multiplication. Once we have got the two types of addition, we simply need to implement the negation (–complex) in order for Mosel to be able to deduce subtraction (real – complex and complex – complex):
static int cx_neg(XPRMcontext ctx, void *libctx) { s_complex *c1; c1=XPRM_POP_REF(ctx); if(c1!=NULL) { c1->re=-c1->re; c1->im=-c1->im; } XPRM_PUSH_REF(ctx,c1); return XPRM_RT_OK; }
For division, we need to implement all three cases since this operation is not commutative: complex/complex, complex/real and real/complex. Since these functions again are similar to the implementations of the other arithmetic operations that have been shown, they are not printed here.
Identity elements for addition and multiplication
In the list of operators printed in the previous section, there appear two more operators: @0 and @1. These two generate the identity elements for addition and multiplication respectively:
static int cx_zero(XPRMcontext ctx, void *libctx) { XPRM_PUSH_REF(ctx,cx_create(ctx, libctx, NULL, 0)); return XPRM_RT_OK; } static int cx_one(XPRMcontext ctx, void *libctx) { s_complex *complex; complex=cx_create(ctx, libctx, NULL, 0); complex->re=1; XPRM_PUSH_REF(ctx, complex); return XPRM_RT_OK; }
Once addition and the 0-element have been defined, Mosel deduces the aggregate operator SUM. With multiplication and the 1-element, we obtain the aggregate operator PROD for our new type.
© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.