Wait, but what's e^N?

7

Objective:

The objective is to calculate e^N for some real or imaginary N (e.g. 2, -3i, 0.7, 2.5i, but not 3+2i). This is code golf, so, shortest code (in bytes) wins.

So, for example:

  1. N = 3, e^N = 20.0855392
  2. N = -2i, e^N = -0.416146837 - 0.9092974268i

The letter i shouldn't be capitalized (since in math it is lowercase)

If your language supports raising numbers to complex numbers, you can't use that. You may use built-in real exponentiation.

For any answer where b (in a + bi) is negative, it is OK to have both the plus and minus sign (e.g. 2 + -3i), since that is understood to be (2 - 3i)

Bonus (-15 bytes): Solve this for N is a any complex number (e.g. 5 + 7i). If you are going for the bonus, you can assume that both components will always be given (even for the standard objective)

mmk

Posted 2014-11-23T15:07:42.073

Reputation: 253

And J uses ajb. – Adám – 2016-08-04T19:38:02.560

Is N always an (imaginary) integer? – Adám – 2016-08-04T19:48:18.893

Can we print a double struck i, provided we don't actually use complex arithmetic in the code? – Martin Ender – 2014-11-25T14:08:44.817

@mmk See the image in belisarius's comment on my Mathematica answer. May the i in the output look like that, or does it have to be ASCII code 0x69? – Martin Ender – 2014-11-26T02:19:07.077

@MartinBüttner, as long as it isn't capitalized, it is OK. – mmk – 2014-11-26T02:26:56.623

what are acceptable in/out formats? A list of 2 numbers? a+bi? r theta? native representation (APL represent complex numbers as aJb)? – TwiNight – 2014-11-26T10:39:42.587

Answers

5

Mathematica, 23 20 bytes - 15 = 5

E^#(Cos@#2+Sin@#2I)&

This is an anonymous function taking two arguments (real and imaginary component). You should supply floats unless you want exact result (with square roots and exponentials). So you can use this like

E^#(Cos@#2+Sin@#2I)&[3.0,-2.0]

Note that I is Mathematica's imaginary unit, but I'm not actually using any complex arithmetic. Also note, that Mathematica will actually print the result using a (double-struck) lowercase i as required. See the screenshot in belisarius's comment.

Martin Ender

Posted 2014-11-23T15:07:42.073

Reputation: 184 808

Perhaps there is some subtlety I don't see, but E^# (Cos@#2 + Sin@#2 I) & seems to work – Dr. belisarius – 2014-11-25T03:53:59.793

@belisarius, I don't want to use I because the question asks for lowercase i, and at least Mma 10 doesn't distribute that multiplication. If you can confirm that Mma 9 does, I'll change it. – Martin Ender – 2014-11-25T09:37:15.087

http://i.stack.imgur.com/YnPhC.png – Dr. belisarius – 2014-11-25T11:51:39.913

And no, with the letter "i", it doesn't distribute – Dr. belisarius – 2014-11-25T11:53:12.833

You lucky!, I cannot reduce any chars using a function in CJam :/ – Optimizer – 2014-11-27T11:03:30.200

7

CJam, 22 - 15 = 7

l~_mc\ms@me:X*\X*'+@'i

Try it online here

Takes input in the form of a b where a is the real component and b is the complex.

For ex. 2i is

0 2

gives

-0.4161468365471424+0.9092974268256817i

Optimizer

Posted 2014-11-23T15:07:42.073

Reputation: 25 836

7

80386 Assembly (41 bytes - 15 = 26)

8B 4C 24 04 8B 54 24 08 D9 EA DC 09 D9 C0 D9 FC DC E9 D9 C9 D9 F0 D9 E8 DE C1 D9 FD DD 02 D9 FB D8 CA DD 19 D8 C9 DD 1A C3

Floating point math in assembly is a pain..

This is a function (cdecl calling convention) that calculates e^(a+bi) via the relation e^(a+bi)=e^a cos b + e^a sin b * i. (It accepts two double * parameters, a and b in that order, and outputs the real part into the a pointer, and the imaginary part into the b pointer).

The function prototype in C would be:

void __attribute__((cdecl)) exp_complex(double *a, double *b);

About half (20, to be exact) of the 41 bytes were spent calculating e^a; another 8 were spent getting the function arguments into registers.

The above bytecode was written by hand, from the following assembly (NASM-style, commented):

; get pointers into ecx, edx
mov ecx, [esp+4] ; 8B 4C 24 04
mov edx, [esp+8] ; 8B 54 24 08

; log(2,e)
fldl2e           ; D9 EA
; a log(2,e)
fmul qword [ecx] ; DC 09
; duplicate
fld st0          ; D9 C0
; get integer part
frndint          ; D9 FC
; get fractional part
fsub st1, st0    ; DC E9
; put fractional part on top
fxch st1         ; D9 C9
; 2^(fract(a log(2,e))) - 1
f2xm1            ; D9 F0
; 2^(fract(a log(2,e)))
fld1             ; D9 E8
faddp st1        ; DE C1
; 2^(fract(a log(2,e))) * 2^(int(a log(2,e)))
; = e^a
fscale           ; D9 FD

; push b
fld qword [edx]  ; DD 02
; sin and cos
fsincos          ; D9 FB
; e^a cos b
fmul st2         ; D8 CA
; output as real part
fstp qword [ecx] ; DD 19
; e^a sin b
fmul st1         ; D8 C9
; output as imaginary part
fstp qword [edx] ; DD 1A

; exit
ret              ; C3

To try this in C (gcc, linux, intel processor):

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

int main(){
    // bytecode from earlier
    char code[] = {
        0x8B, 0x4C, 0x24, 0x04, 0x8B, 0x54, 0x24, 0x08,
        0xD9, 0xEA, 0xDC, 0x09, 0xD9, 0xC0, 0xD9, 0xFC,
        0xDC, 0xE9, 0xD9, 0xC9, 0xD9, 0xF0, 0xD9, 0xE8,
        0xDE, 0xC1, 0xD9, 0xFD, 0xDD, 0x02, 0xD9, 0xFB,
        0xD8, 0xCA, 0xDD, 0x19, 0xD8, 0xC9, 0xDD, 0x1A,
        0xC3,
    };
    // allocate executable memory to a function pointer called 'exp_complex'
    void __attribute__( (__cdecl__) ) (*exp_complex)(double *,double *) = mmap(0,sizeof code,PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE,-1,0);
    memcpy(exp_complex, code, sizeof code);

    // test inputs
    double a = 42.24, b = -2.7182818;

    printf("%.07g + %.07g i\n", a, b);

    // call bytecode as a c function
    exp_complex(&a, &b);

    printf("%.07g + %.07g i\n", a, b);

    // release allocated memory
    munmap(exp_complex, sizeof code);

    return 0;
}

es1024

Posted 2014-11-23T15:07:42.073

Reputation: 8 953

4

ES6, 63 56 55 bytes - 15 = 40

(a,b)=>(m=Math,e=m.exp(a),e*m.cos(b)+`+${e*m.sin(b)}i`)

This is a function that accepts a number in the form a + bi with a and b as the function arguments.

It uses Euler's formula e^ix=cosx+isinx.

Peter Olson

Posted 2014-11-23T15:07:42.073

Reputation: 7 412

1Sorry for the almost-3-year lag, but you can save 2 char by combining variable assignment with the evaluations: (a,b)=>(e=(m=Math).exp(a))*m.cos(b)+`+${e*m.sin(b)}i` – Shieru Asakoto – 2017-10-11T08:24:12.203

You can use parentheses and the comma operator to drop return: (a,b)=>(m=Math,e=m.exp(a),e*m.cos(b)+"+"+e*m.sin(b)+"i") – Ry- – 2014-11-23T16:55:23.720

You can save 1 char using template strings: (a,b)=>(m=Math,e=m.exp(a),e*m.cos(b)+\+${e*m.sin(b)}i`)`

– Oriol – 2014-11-23T21:58:22.417

4

TI-BASIC (NSpire) 13 (28 bytes-15)

f(r,j):=^r*(sin(j)i+cos(j

The is e. This computes e^z for z=r+i*j. i is an undefined variable. This defines a function f which accepts two parameters: the real part and the imaginary part.

Shujal

Posted 2014-11-23T15:07:42.073

Reputation: 687

i isn't an undefined variable on 83/84 calculators; I'm not sure about the Nspire. Could you check what i^2 gives on the calculator? I don't have one. – tomsmeding – 2014-11-23T16:37:05.483

1How are r and j provided ? We have to write either a function that takes input from arguments or a complete program taking input from ARGV or STDIN. I can very well write a CJam program of 0 score if I follow your approach. – Optimizer – 2014-11-23T16:43:36.023

i is different depending on how it's entered. Entered as a character on the keyboard it refers to the variable, while entered through a special way it refers to sqrt(-1). – Octavia Togami – 2014-11-23T17:53:59.327

@tomsmeding this works on models that actually have symbolic variables (89, 92, nspire, and the like), where a variable that isn't given a value is just a symbol. i is i and i^2 is i^2. – hobbs – 2014-11-23T18:35:43.737

1The added cost should be 14 for Define f(r,j)= – hobbs – 2014-11-23T18:37:51.563

3

Haskell 30 raw, 15 with bonus:

e a b=map(*exp a)[cos b,sin b]

load it up into the GHCi, then try out the function:

Ok, modules loaded: Main.
*Main> e 3 0
[20.085536923187668,0.0]
*Main> e 0 (-2)
[-0.4161468365471424,-0.9092974268256817]

Also, humans can understand why this works :)

I hope the GHCi is a code golf legal way of bringing Haskell in. Also note that a human must infer that the second field is the complex one. [edit1]

Rentsy

Posted 2014-11-23T15:07:42.073

Reputation: 151

2

BBC BASIC - 44 bytes (with tokenisation) - 15 = 29

Put this after the END statement. Arguments are the same as

a+bi = (a,b)

Code

DEFFNf(a,b)e=EXPa:=STR$(e*COSb)+"+"+STR$(e*SINb)+"i"

Usage

imaginary$ = FNf(1,1)
PRINT imaginary$
END
DEFFNf(a,b)e=EXPa:=STR$(e*COSb)+"+"+STR$(e*SINb)+"i"

Where the output is:

1.46869394+2.28735529i

Beta Decay

Posted 2014-11-23T15:07:42.073

Reputation: 21 478

1

CJam, 33 bytes

l_"i"&{);d_mc\ms_0<!'+*\'i}{dme}?

Test it here.

This supports only purely real or purely imaginary input.

Martin Ender

Posted 2014-11-23T15:07:42.073

Reputation: 184 808

0

C (gcc), 51 47 bytes - 15 = 32

#define f(x)(cos((x)*1i)-1i*sin(1i*(x)))*exp(x)

Try it online!

ceilingcat

Posted 2014-11-23T15:07:42.073

Reputation: 5 503

0

Dyalog APL, 20 - 15 = 5 bytes

,'+i',⍨(⍪(*⊣)×2 1○⊢)

, flatten
'+i',⍨ "+i" appended to
     the (2 rows, 1 column) table of
        * e to the power of
         the left argument (the real part)
    × times
    2 1○ the cosine and sine of
     the right argument (the imaginary part)

TryAPL online!

Adám

Posted 2014-11-23T15:07:42.073

Reputation: 37 779

0

Python, (94 - 15) = 79 bytes

from math import *
import cmath
n=input()
print `e**(n[0])*(cos(n[1])+1j*sin(n[1]))`[1:-2]+'i'

Pretty straightforward implementation. Since python uses "j" instead of "i" for imaginary numbers, replacing the characters in the final string eats up quite a few (12) bytes. This can definitely still be golfed.

Takes input in the form of [a,b] for a + bi.

Theo

Posted 2014-11-23T15:07:42.073

Reputation: 348

I think you can remove the space in 'print `' and why do you need cmath? – TuxCrafting – 2016-08-18T18:12:25.273