Euler's identity

From Rosetta Code
Euler's identity is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
This page uses content from Wikipedia. The original article was at Euler's_identity. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)

In mathematics, Euler's identity (also known as Euler's equation) is the equality:

   e + 1 = 0

where

   e is Euler's number, the base of natural logarithms,
   i is the imaginary unit, which satisfies i2 = −1, and
   π is pi, the ratio of the circumference of a circle to its diameter.

Euler's identity is often cited as an example of deep mathematical beauty. Three of the basic arithmetic operations occur exactly once each: addition, multiplication, and exponentiation. The identity also links five fundamental mathematical constants:

   The number 0.
   The number 1.
   The number π (π = 3.141...).
   The number e (e = 2.718...), which occurs widely in mathematical analysis.
   The number i, the imaginary unit of the complex numbers.
Task

Show in your language that Euler's identity is true. As much as possible and practical, mimic the Euler's identity equation.

Most languages are limited to IEEE 754 floating point calculations so will have some error in the calculation. If that is the case, or there is some other limitation, show that e + 1 is approximately equal to zero and show the amount of error in the calculation.

If your language is capable of symbolic calculations, show that e + 1 is exactly equal to zero for bonus kudos points.

ALGOL 68[edit]

Whilst Algol 68 has complex numbers as standard, it does not have a standard complex exp function.
We could use the identity exp(x + iy) = exp(x)( cos y + i sin y ), however the following uses a series expansion for exp(ix).

BEGIN
# calculate an approximation to e^(i pi) + 1 which should be 0 (Euler's identity) #
 
# returns e^ix for long real x, using the series: #
# exp(ix) = 1 - x^2/2! + x^4/4! - ... + i(x - x^3/3! + x^5/5! - x^7/7! ... ) #
# the expansion stops when successive terms differ by less than 1e-15 #
PROC expi = ( LONG REAL x )LONG COMPL:
BEGIN
LONG REAL t := 1;
LONG REAL real part := 1;
LONG REAL imaginary part := 0;
LONG REAL divisor := 1;
BOOL even power := FALSE;
BOOL subtract := FALSE;
LONG REAL diff := 1;
FOR n FROM 1 WHILE ABS diff > 1e-15 DO
divisor *:= n;
t *:= x;
LONG REAL term := t / divisor;
IF even power THEN
# this term is real #
subtract := NOT subtract;
LONG REAL prev := real part;
IF subtract THEN
real part -:= term
ELSE
real part +:= term
FI;
diff := prev - real part
ELSE
# this term is imaginary #
LONG REAL prev := imaginary part;
IF subtract THEN
imaginary part -:= term
ELSE
imaginary part +:= term
FI;
diff := prev - imaginary part
FI;
even power := NOT even power
OD;
( real part, imaginary part )
END # expi # ;
LONG COMPL eulers identity = expi( long pi ) + 1;
print( ( "e^(i*pi) ~ "
, fixed( re OF eulers identity, -23, 20 )
, " "
, fixed( im OF eulers identity, 23, 20 )
, "i"
, newline
)
)
END
Output:
e^(i*pi) ~  0.00000000000000000307 -0.00000000000000002926i

C[edit]

The C99 standard did, of course, introduce built-in support for complex number arithmetic into the language and so we can therefore compute (e ^ πi + 1) directly without having to resort to methods which sum the power series for e ^ x.

The following code has been tested with gcc 5.4.0 on Ubuntu 16.04.

#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <wchar.h>
#include <locale.h>
 
int main() {
wchar_t pi = L'\u03c0'; /* Small pi symbol */
wchar_t ae = L'\u2245'; /* Approximately equals symbol */
double complex e = cexp(M_PI * I) + 1.0;
setlocale(LC_CTYPE, "");
printf("e ^ %lci + 1 = [%.16f, %.16f] %lc 0\n", pi, creal(e), cimag(e), ae);
return 0;
}
Output:
e ^ πi + 1 = [0.0000000000000000, 0.0000000000000001] ≅ 0

C++[edit]

#include <iostream>
#include <complex>
 
int main() {
std::cout << std::exp(std::complex<double>(0.0, M_PI)) + 1.0 << std::endl;
return 0;
}
Output:

Zero and a little floating dust ...

(0,1.22465e-16)

Factor[edit]

USING: math math.constants math.functions prettyprint ;
1 e pi C{ 0 1 } * ^ + .
Output:
C{ 0.0 1.224646799147353e-016 }

Go[edit]

package main
 
import (
"fmt"
"math"
"math/cmplx"
)
 
func main() {
fmt.Println(cmplx.Exp(math.Pi * 1i) + 1.0)
}
Output:

Zero and a little floating dust ...

(0+1.2246467991473515e-16i)

Haskell[edit]

A double is not quite real.

import Data.Complex
 
eulerIdentityZeroIsh :: Complex Double
eulerIdentityZeroIsh =
exp (0 :+ pi) + 1
 
main :: IO ()
main = print eulerIdentityZeroIsh
Output:

Zero and a little floating dust ...

0.0 :+ 1.2246467991473532e-16

Julia[edit]

Works with: Julia version 0.6

Julia has a builtin Complex{T} parametrized type.

@show e ^ (π * im) + 1
@assert e ^ (π * im) ≈ -1
Output:
e ^ (π * im) + 1 = 0.0 + 1.2246467991473532e-16im

Using symbolic algebra, through the Reduce.jl package.

using Reduce
@force using Reduce.Algebra
 
@show e ^ (π * :i) + 1
@assert e ^ (π * :i) + 1 == 0
Output:
e ^ (π * :i) + 1 = 0

Kotlin[edit]

As the JVM lacks a complex number class, we use our own which has sufficient operations to perform this task.

e ^ πi is calculated by summing successive terms of the power series for e ^ x until the modulus of the difference between terms is no longer significant given the precision of the Double type (about 10 ^ -16).

// Version 1.2.40
 
import kotlin.math.sqrt
import kotlin.math.PI
 
const val EPSILON = 1.0e-16
const val SMALL_PI = '\u03c0'
const val APPROX_EQUALS = '\u2245'
 
class Complex(val real: Double, val imag: Double) {
operator fun plus(other: Complex) =
Complex(real + other.real, imag + other.imag)
 
operator fun times(other: Complex) = Complex(
real * other.real - imag * other.imag,
real * other.imag + imag * other.real
)
 
fun inv(): Complex {
val denom = real * real + imag * imag
return Complex(real / denom, -imag / denom)
}
 
operator fun unaryMinus() = Complex(-real, -imag)
 
operator fun minus(other: Complex) = this + (-other)
 
operator fun div(other: Complex) = this * other.inv()
 
val modulus: Double get() = sqrt(real * real + imag * imag)
 
override fun toString() =
if (imag >= 0.0) "$real + ${imag}i"
else "$real - ${-imag}i"
}
 
fun main(args: Array<String>) {
var fact = 1.0
val x = Complex(0.0, PI)
var e = Complex(1.0, PI)
var n = 2
var pow = x
do {
val e0 = e
fact *= n++
pow *= x
e += pow / Complex(fact, 0.0)
}
while ((e - e0).modulus >= EPSILON)
e += Complex(1.0, 0.0)
println("e^${SMALL_PI}i + 1 = $e $APPROX_EQUALS 0")
}
Output:
e^πi + 1 = -8.881784197001252E-16 - 9.714919754267985E-17i ≅ 0

OCaml[edit]

# open Complex;;
# let pi = acos (-1.0);;
val pi : float = 3.14159265358979312
# add (exp { re = 0.0; im = pi }) { re = 1.0; im = 0.0 };;
- : Complex.t = {re = 0.; im = 1.22464679914735321e-16}

Perl[edit]

use Math::Complex;
print exp(pi * i) + 1, "\n";
Output:
1.22464679914735e-16i

Perl 6[edit]

Works with: Rakudo version 2018.03

Implementing an "invisible times" operator (Unicode character (U+2062)) to more closely emulate the layout. Alas, Perl 6 does not do symbolic calculations at this time and is limited to IEEE 754 floating point for transcendental and irrational number calculations.

e, i and π are all available as built-in constants in Perl 6.

sub infix:<> is tighter(&infix:<**>) { $^a * $^b };
 
say 'e**i⁢π + 1 ≅ 0 : ', e**i⁢π + 10;
say 'Error: ', e**i⁢π + 1;
Output:
e**i⁢π + 1 ≅ 0 : True
Error: 0+1.2246467991473532e-16i

Python[edit]

>>> import math
>>> math.e ** (math.pi * 1j) + 1
1.2246467991473532e-16j

Racket[edit]

#lang racket
(+ (exp (* 0+i pi)) 1)
Output:
0.0+1.2246063538223773e-016i

Ruby[edit]

> require 'complex'
> Math::E ** (Math::PI * Complex::I) + 1
=> (0.0+0.0i)

Sidef[edit]

say ('e**i⁢π + 1 ≅ 0 : ', Num.e**Num.pi.i + 10)
say ('Error: ', Num.e**Num.pi.i + 1)
Output:
e**i⁢π + 1 ≅ 0 : true
Error: -2.42661922624586582047028764157944836122122513308e-58i

zkl[edit]

var [const] GSL=Import("zklGSL");	// libGSL (GNU Scientific Library)
Z,pi,e := GSL.Z, (0.0).pi, (0.0).e;
 
println("e^(\u03c0i) + 1 = %s \u2245 0".fmt( Z(e).pow(Z(0,1)*pi) + 1 ));
println("TMI: ",(Z(e).pow(Z(0,1)*pi) + 1 ).format(0,25,"g"));
Output:
e^(πi) + 1 = (0.00+0.00i) ≅ 0
TMI: (0+1.224646799147353207173764e-16i)