# Complex number

This is module to calculate imaginary number.

The imaginary unit is represented by `i`.

author
- PiotrLi
- GPL

/

```   11:-module(complex,[
12             set_default_is/3,
13             op(700,xfx,iis),
14             iis/2,
15             op(700,xfx,c_equals),
16             c_equals/2,
17             complex_canonical/3,
18             is_canonical/3,
19             complex_exponential/3,
20             is_exponential/3,
21             complex_number/1
22         ]).   23:-op(700,xfx,iis).   24:-op(700,xfx,c_equals).   25
26:-dynamic a_default_is/3.   27a_default_is(is(A,B),A,B).```
set_default_is(F, A, B) is det
Set function for iis/2 if you don't want use is/2.

Example:

```?- [user].
|: my_the_best_is(A,B):-
|: var(A),
|: nonvar(B),
|: A is B,
|: format('~w is ~w\n',[A,B]).
|: ^D% user://1 compiled 0.00 sec, 1 clauses
true.

?- set_default_is(my_the_best_is(A,B),A,B).
true.

?- X iis 3+i*5+15.
3 is 3
15 is 15
18 is 3+15
5 is 5+0
X = 18+5*i.

?- X iis 15**(3*i).
8.12415060330663 is log(15**3)
X = exp(i*8.12415060330663).
```
```   60set_default_is(F,A,B):-
61    retractall(a_default_is(_,_,_)),
62    asserta(a_default_is(F,A,B)).
63
64default_is(A,B):-
65    a_default_is(C,A,B),
66    call(C).```
iis(-Number, ++Expr) is det
It is is/2 witch imaginary number.
abs(+Z)
Return modulus of Z.
phase(+Z)
Return phase of Z, normalized to be between -pi and pi.
real(+Z)
Return real part of Z.
imaginary(+Z)
Return imaginary part of Z.
conjugate(+Z)
Return the conjugate of Z.
reciprocal(+Z)
Return the reciprocal of Z.
exp(+Z)
Return the complex exponential of Z.
sin(+Z)
Return the complex sine of Z.
cos(+Z)
Return the complex cosine of Z.
tan(+Z)
Return the complex tangent of Z.

Examples:

```?- X iis i*i.
X = -1.

?- X iis 5*i*6*7.
X = 210*i.

?- X iis 5*i+3.
X = 3+5*i.

?- X iis phase(2+3*i).
X = 0.982793723247329.

?- X iis abs(5+10*i).
X = 11.180339887498949.

?- X iis conjugate(1+5*i).
X = 1-5*i.

?- X iis imaginary(5+2*i).
X = 2.

?- X iis imaginary(sqrt(2)*exp(45*pi/180*i)).
X = 1.0.

?- X iis 6*i*5/(i*2*5).
X = 3.
```
```  133%  like normal (is)/2
134% ---------------
135
136(_ iis Y):-
137    \+ ground(Y),
138    throw(error(instantiation_error, context(complex:(iis)/2, _))).
139
140(X iis Y):-
141    catch(default_is(Z,Y),_,(!,fail)),!,
142    X = Z.
143
144(R+I*i iis X):-
145    complex_canonical(X,R,I),!.
146
147%  Functions
148% -----------
149(M iis abs(Z)):-
150    ZZ iis Z,
151    complex_exponential(ZZ,M,_),!.
152
153(F iis phase(Z)):-
154    ZZ iis Z,
155    complex_exponential(ZZ,_,F),!.
156
157(R iis real(Z)):-
158    ZZ iis Z,
159    complex_canonical(ZZ,R,_),!.
160
161(I iis imaginary(Z)):-
162    ZZ iis Z,
163    complex_canonical(ZZ,_,I),!.
164
165(R-I*i iis conjugate(Z)):-
166    ZZ iis Z,
167    complex_canonical(ZZ,R,I),!.
168
169(X iis reciprocal(Z)):-
170    ZZ iis Z,
171    complex_canonical(ZZ,R,I),
172    default_is(S,R*R+I*I),
173    X iis R/S + I/S*i,!.
174
175(X iis sqrt(Z)):-!,
176    X iis Z**0.5.
177
178(X iis exp(Z)):-
179    ZZ iis Z,
180    complex_canonical(ZZ,R,I),
181    X iis exp(R)*cos(I) + exp(R)*sin(I)*i,!.
182
183(X iis sin(Z)):-
184    ZZ iis Z,
185    complex_canonical(ZZ,R,I),
186    X iis sin(R)*cosh(I) + cos(R)*sinh(I)*i,!.
187
188(X iis cos(Z)):-
189    ZZ iis Z,
190    complex_canonical(ZZ,R,I),
191    X iis cos(R)*cosh(I) + sin(R)*sinh(I)*i,!.
192
193(X iis tan(Z)):-
194    ZZ iis Z,
195    complex_number(ZZ),
196    X iis sin(ZZ)/cos(ZZ),!.
197
198(X iis ctan(Z)):-
199    ZZ iis Z,
200    complex_number(ZZ),
201    X iis cos(ZZ)/sin(ZZ),!.
202
203%  Optimize
204% ----------
205
206(i iis i):-!.
207
208(-1 iis i*i):-!.
209
210(0 iis 0*i):-!.
211
212(0 iis 0.0*i):-!.
213
214(i iis 1*i):-!.
215
216(i iis 1.0*i):-!.
217
218(-1 iis e**(i*pi)):-!.
219
220(-1 iis e**(pi*i)):-!.
221
222(AA*i iis A*i):-
223    number(A),!,
224    AA=A.
225
226(0 iis O1+O2*i):-
227    zero(O1),
228    zero(O2),!.
229(0 iis O1-O2*i):-
230    zero(O1),
231    zero(O2),!.
232
233(R iis R+O*i):-
234    number(R),
235    zero(O),!.
236(I*i iis O+I*i):-
237    number(I),
238    zero(O),!.
239(II*i iis O-I*i):-
240    number(I),
241    zero(O),!,
242    default_is(II,-I).
243
244(R-II*i iis R+I*i):-
245    number(R),
246    number(I),
247    I<0,!,
248    default_is(II,-I).
249
250(R+II*i iis R-I*i):-
251    number(R),
252    number(I),
253    I<0,!,
254    default_is(II,-I).
255
256/*
257(X iis X):-
258    complex_number(X),!.
259*/
260
261%  Plus
262% ------
263(R iis R-I*i + I*i):-!.
264
265(RR+I*i iis A+Z):-
266    number(A),
267    complex_canonical(Z,R,I),!,
268    default_is(RR,A+R).
269
270(X*i iis A*i + B*i):-
271    number(A),
272    number(B),!,
273    default_is(X,A+B).
274
275(R+X*i iis R-A*i + B*i):-
276    number(R),
277    number(A),
278    number(B),!,
279    default_is(X,B-A).
280
281(RR+A*i iis B + R + A*i):-
282    number(R),
283    number(A),
284    number(B),!,
285    default_is(RR,R+B).
286
287
288(RR+A*i iis B + (R + A*i)):-
289    number(R),
290    number(A),
291    number(B),!,
292    default_is(RR,R+B).
293
294(R+X*i iis R+A*i + B*i):-
295    number(R),
296    number(A),
297    number(B),!,
298    default_is(X,A+B).
299
300(RR+II*i iis Z1+Z2):-
301    complex_canonical(Z1,R1,I1),
302    complex_canonical(Z2,R2,I2),!,
303    default_is(RR,R1+R2),
304    default_is(II,I1+I2).
305
306(X iis A+B):-
307    AA iis A,
308    BB iis B,
309    complex_number(AA),
310    complex_number(BB),!,
311    XX iis AA+BB,
312    X=XX.
313
314%  Minus
315% -------
316(0 iis I*i - I*i):-
317    number(I),!.
318
319(I*i iis R+I*i - R):-!.
320
321(R iis R+I*i - I*i):-!.
322
323(I*i iis I1*i - I2*i):-
324    number(I1),
325    number(I2),!,
326    default_is(I,I1-I2).
327
328(R-X*i iis R-A*i - B*i):-
329    number(R),
330    number(A),
331    number(B),!,
332    default_is(X,A+B).
333
334(R+X*i iis R+A*i - B*i):-
335    number(R),
336    number(A),
337    number(B),!,
338    default_is(X,A-B).
339
340
341(RR+I*i iis Z-A):-
342    number(A),
343    complex_canonical(Z,R,I),!,
344    default_is(RR,R-A).
345
346(RR+II*i iis Z1-Z2):-
347    complex_canonical(Z1,R1,I1),
348    complex_canonical(Z2,R2,I2),!,
349    default_is(RR,R1-R2),
350    default_is(II,I1-I2).
351
352(X iis A-B):-
353    AA iis A,
354    BB iis B,
355    complex_number(AA),
356    complex_number(BB),!,
357    XX iis AA-BB,
358    X=XX.
359
360%  Time
361% ------
362(A*i iis i*A):-
363    number(A),!.
364
365(-A iis A*i*i):-
366    number(A),!.
367
368(X iis A*i*B*i):-
369    number(A),
370    number(B),!,
371    default_is(X,-A*B).
372
373(I*i iis A*i*B):-
374    number(A),
375    number(B),!,
376    default_is(I,A*B).
377
378(C*exp(i*H) iis A*exp(i*F)*(B*exp(i*G))):-
379    number(A),
380    number(B),
381    number(F),
382    number(G),!,
383    default_is(C,A*B),
384    default_is(H,F+G).
385
386% different brackets
387(C*exp(i*H) iis A*exp(i*F)*B*exp(i*G)):-
388    number(A),
389    number(B),
390    number(F),
391    number(G),!,
392    default_is(C,A*B),
393    default_is(H,F+G).
394
395(C*exp(i*G) iis A*(B*exp(i*G))):-
396    number(A),
397    number(B),
398    number(G),!,
399    default_is(C,A*B).
400
401% different brackets
402(C*exp(i*G) iis A*B*exp(i*G)):-
403    number(A),
404    number(B),
405    number(G),!,
406    default_is(C,A*B).
407
408
409(RR+II*i iis A*Z):-
410    number(A),
411    complex_canonical(Z,R,I),!,
412    default_is(RR,A*R),
413    default_is(II,A*I).
414
415(RR+II*i iis Z1*Z2):-
416    complex_canonical(Z1,R1,I1),
417    complex_canonical(Z2,R2,I2),!,
418    default_is(RR,R1*R2 - I1*I2),
419    default_is(II,R1*I2 + I1*R2).
420
421(X iis A*B):-
422    AA iis A,
423    BB iis B,
424    complex_number(AA),
425    complex_number(BB),!,
426    XX iis AA*BB,
427    X=XX.
428
429%  Divide
430% -------
431(1 iis i/i):-!.
432(C*i iis i/A):-
433    number(A),!,
434    default_is(C,1/A).
435(C iis i/(A*i)):-
436    number(A),!,
437    default_is(C,1/A).
438(A iis A*i/i):-
439    number(A),!.
440(C iis A*i/(B*i)):-
441    number(A),
442    number(B),!,
443    default_is(C,A/B).
444(C*i iis A*i/B):-
445    number(A),
446    number(B),!,
447    default_is(C,A/B).
448
449
450(RR+II*i iis A/B):-
451    number(B),
452    AA iis A,
453    complex_canonical(AA,R,I),!,
454    default_is(RR,R/B),
455    default_is(II,I/B).
456
457(X iis A/B):-
458    complex_number(A),
459    complex_number(B),
460    X iis A*reciprocal(B),!.
461
462(X iis A/B):-
463    AA iis A,
464    BB iis B,
465    complex_number(AA),
466    complex_number(BB),!,
467    XX iis AA/BB,
468    X=XX.
469
470%  Exponentiation
471% ----------------
472(W iis i**N):-
473    integer(N),
474    default_is(K,N mod 4),
475    (   K=0,!,
476        W=1
477    ;   K=1,!,
478        W=i
479    ;   K=2,!,
480        W= -1
481    ;   K=3,!,
482        W= -i
483    ).
484
485(exp(i*P) iis i**A):-
486    number(A),!,
487    default_is(P,pi*A/2).
488
489(X iis -1**i):-!,
490    default_is(X,exp(-pi)).
491(X iis -1.0**i):-!,
492    default_is(X,exp(-pi)).
493
494(X iis A**i):-
495    number(A),!,
496    (   A>0,!,
497        default_is(L,log(A)),
498        X = exp(i*L)
499    ;   A<0,!,
500        default_is(L,log(-A)),
501        default_is(M,exp(-pi)),
502        X = M*exp(i*L)
503    ;   X=0
504    ).
505
506(X iis Z**i):-
507    complex_exponential(Z,M,P),!,
508    default_is(A,e**(-P)),
509    X iis A*M**i.
510
511(exp(i*L) iis A**(B*i)):-
512    number(A),
513    number(B),!,
514    catch(
515        catch(
516            default_is(L,log(A**B)),
517            error(evaluation_error(float_overflow),_),
518            L is B*log(A)
519        ),
520        error(evaluation_error(undefined), context(log/1, _)),
521        (   A = 0,
522            L = 0
523        ;   L is log(A)
524        )
525    ).
526
527(A*E iis Z**i):-
528    complex_exponential(Z,M,P),!,
529    default_is(A,e**(-P)),
530    E iis M**i.
531
532
533(AA*exp(i*PP) iis Z**N):-
534    number(N),
535    complex_exponential(Z,A,P),!,
536    default_is(AA,A**N),
537    default_is(PP,P*N).
538
539(XX iis N**Z):-
540    number(N),
541    complex_canonical(Z,A,B),!,
542    default_is(M,N**A),
543    E iis N**(B*i),
544    (   E = exp(_),
545        XX = M*E
546    ;   XX iis M*E
547    ).
548
549(X iis Z**Z2):-
550    complex_exponential(Z,M,P),
551    complex_canonical(Z2,A,B),!,
552    default_is(MM,M**A),
553    exp(P1) iis M**(B*i),
554    P2 iis i*P*Z2,
555    PP iis P1+P2,
556    X iis MM*exp(PP).
557
558
559(X iis N**Z):-
560    number(N),
561    complex_canonical(Z,R,I),!,
562    default_is(A,N**R),
563    B iis N**(I*i),
564    X iis A*B.
565
566(X iis A**B):-
567    AA iis A,
568    BB iis B,
569    complex_number(AA),
570    complex_number(BB),!,
571    XX iis AA**BB,
572    XX = X.
573
574(X iis A^B):-
575    X iis A ** B.```
c_equals(@Term1, @Term2) is det
It is for (iis)/2, like (=:=)/2 for (is)/2.
```  582c_equals(A,B):-
583    Z1 iis A,
584    complex_canonical(Z1,R1,I1),
585    Z2 iis B,
586    complex_canonical(Z2,R2,I2),
587    R1==R2,
588    I1==I2.```
complex_canonical(+Complex, -Real:number, -Imaginary:number) is semidet
Get real and imaginary from complex number and test if `complex_number(Complex)` in the same time.
```  595% canonical
596complex_canonical(i,0,1):-!.
597complex_canonical(-i,0,-1):-!.
598complex_canonical(R,R,0):-
599    number(R),!.
600complex_canonical(I*i,0,I):-
601    number(I),!.
602complex_canonical(R+i,R,1):-
603    number(R),!.
604complex_canonical(R+I*i,R,I):-
605    number(R),
606    number(I),!.
607complex_canonical(R-i,R,-1):-
608    number(R),!.
609complex_canonical(R-II*i,R,I):-
610    number(R),
611    number(II),!,
612    default_is(I,-II).
613
614% exponential
615complex_canonical(exp(i),R,I):-!,
616    default_is(R,cos(1)),
617    default_is(I,sin(1)).
618complex_canonical(exp(i*F),R,I):-
619    number(F),!,
620    default_is(R,cos(F)),
621    default_is(I,sin(F)).
622complex_canonical(M*exp(i),R,I):-
623    number(M),!,
624    default_is(R,M*cos(1)),
625    default_is(I,M*sin(1)).
626complex_canonical(M*exp(i*F),R,I):-
627    number(M),
628    number(F),!,
629    pol_rec(R,I,M,F).
630
631% trigonometric
632complex_canonical(cos(F)+i*sin(F),R,I):-
633    number(F),!,
634    pol_rec(R,I,1,F).
635complex_canonical(M*(cos(F)+i*sin(F)),R,I):-
636    number(M),
637    number(F),!,
638    pol_rec(R,I,M,F).```
is_canonical(+Z, -Real:number, -Imaginary:number) is semidet
Get real and imaginary from complex number and test if Complex is in canonical in the same time.
```  646is_canonical(i,0,1):-!.
647is_canonical(-i,0,-1):-!.
648is_canonical(R,R,0):-
649    number(R),!.
650is_canonical(I*i,0,I):-
651    number(I),!.
652is_canonical(R+i,R,1):-
653    number(R),!.
654is_canonical(R+I*i,R,I):-
655    number(R),
656    number(I),!.
657is_canonical(R-i,R,-1):-
658    number(R),!.
659is_canonical(R-II*i,R,I):-
660    number(R),
661    number(II),!,
662    default_is(I,-II).```
complex_exponential(+Complex, -Abs:number, -Phase:number) is semidet
Get abs and phase from complex number and test if `complex_number(Complex)` in the same time
```  670% canonical
671complex_exponential(i,1,F):-!,
672    default_is(F,pi/2).
673complex_exponential(-i,-1,F):-!,
674    default_is(F,pi/2).
675complex_exponential(M,M,0):-
676    number(M),!.
677complex_exponential(M*i,M,F):-
678    number(M),!,
679    default_is(F,pi/2).
680complex_exponential(R+i,M,F):-
681    number(R),!,
682    pol_rec(R,1,M,F).
683complex_exponential(R+I*i,M,F):-
684    number(R),
685    number(I),!,
686    pol_rec(R,I,M,F).
687complex_exponential(R-i,M,F):-
688    number(R),!,
689    pol_rec(R,-1,M,F).
690complex_exponential(R-I*i,M,F):-
691    number(R),
692    number(I),!,
693    default_is(II,-I),
694    pol_rec(R,II,M,F).
695
696% exponential
697complex_exponential(exp(i),1,1):-!.
698complex_exponential(exp(i*F),1,F):-
699    number(F),!.
700complex_exponential(M*exp(i),M,1):-
701    number(M),!.
702complex_exponential(M*exp(i*F),M,F):-
703    number(M),
704    number(F),!.
705
706% trigonometric
707complex_exponential(cos(F)+i*sin(F),1,F):-
708    number(F),!.
709complex_exponential(M*(cos(F)+i*sin(F)),M,F):-
710    number(M),
711    number(F),!.```
is_exponential(+Complex, -Abs:number, -Phase:number) is semidet
Get abs and phase from complex number and test if Complex is in exponential or trigonometric in the same time.
```  718% exponential
719is_exponential(exp(i),1,1):-!.
720is_exponential(exp(i*F),1,F):-
721    number(F),!.
722is_exponential(M*exp(i),M,1):-
723    number(M),!.
724is_exponential(M*exp(i*F),M,F):-
725    number(M),
726    number(F),!.
727
728% trigonometric
729is_exponential(cos(F)+i*sin(F),1,F):-
730    number(F),!.
731is_exponential(M*(cos(F)+i*sin(F)),M,F):-
732    number(M),
733    number(F),!.
734
735
736pol_rec(R,I,M,F):-
737    number(R),
738    number(I),!,
739    default_is(M,sqrt(R*R+I*I)),
740    default_is(F,atan2(I,R)).
741pol_rec(R,I,M,F):-
742    number(M),
743    number(F),!,
744    default_is(R,M*cos(F)),
745    default_is(I,M*sin(F)).```
complex_number(@Complex) is semidet
True if Term currently is a complex number in a form like:
• canonical
`4, i, -1, 2*i, 3+2*i, 8-4*i, 3+ -2*i`
• exponential
`12*exp(i*5), exp(i*12)`
• trigonometric
`10*(cos(3)+i*sin(3)), cos(4)+i*sin(4)`
```  765complex_number(A):-
766    var(A),!,fail.
767
768complex_number(i):-!.
769complex_number(-i):-!.
770complex_number(R):-
771    number(R),!.
772complex_number(R + I*i):-
773    number(R),
774    number(I),!.
775complex_number(R - I*i):-
776    number(R),
777    number(I),!.
778complex_number(R - i):-
779    number(R),!.
780complex_number(exp(i*F)):-
781    number(F),!.
782complex_number(M*exp(i*F)):-
783    number(M),
784    number(F),!.
785complex_number(cos(F)+i*sin(F)):-
786    number(F),!.
787complex_number(M*(cos(F)+i*sin(F))):-
788    number(M),
789    number(F),!.
790complex_number(I):-
791    imaginary_number(I,_),!.
792
793imaginary_number(i,1):-!.
794imaginary_number(I*i,I):-
795    number(I),!.
796
797zero(0):-!.
798zero(0.0):-!.
799zero(-0):-!.
800zero(-0.0):-!.
801
802one(1):-!.
803one(1.0):-!```