# Complex numbers

# Complex numbers#

Instead of `a+bi`

or `a+b×i`

, APL uses `aJb`

for scalar atomic complex numbers. In other words, `3+4i`

is `3J4`

and *i* is `0J1`

. The arithmetic functions support complex mathematics where sensible. Of special interest are monadic `+`

and `|`

and the circular functions `k○Y`

. Monadic `+`

is the complex conjugate, that is, `a+bi → a-bi`

.

```
2J4*0.5
```

1.79890744J1.111785941

We can combine a real and imaginary parts with `re+0J1×im`

but since the complex numbers are atomic (simple scalars) we need a way to split them. For this we have `9○Y`

and `11○Y`

which would be `Re(Y)`

and `Im(Y)`

in traditional notation. You might think it odd that we have numbered functions (like the trigonometric functions; sine and cosine are `1○Y`

and `2○Y`

) but it can actually be really neat because `○`

is a scalar function.

Let’s say we have a vector of complex numbers `Nv←2J3 0J1 10`

then how might we get a 2-row matrix with one row for the real parts and one row for the complex part?

```
Nv←2J3 0J1 10
9 11∘.○Nv
```

2 0 10 3 1 0

Now, if we have an array `N←2 2⍴2J3 0J1 10 0`

and want a two-element vector where each element has the same shape as `N`

but the first has the real parts and the second the imaginary parts?

```
N←2 2⍴2J3 0J1 10 0
9 11○⊂N
```

┌────┬───┐ │ 2 0│3 1│ │10 0│0 0│ └────┴───┘

The solution can be either a tacit function `(9 11○⊂)N`

or the expression `9 11○⊂N`

though the outcome is equivalent. First we enclose `N`

which makes it a scalar. Then we pair that scalar with a vector `9 11`

as arguments to a scalar function, `○`

. This makes APL do a scalar extension: `9 11○(⍴9 11)⍴⊂N`

or `9 11○N N`

or `(9○N)(11○N)`

.

Now, if you’re familiar with the trigonometric functions, you’ll know that negating the left argument of `○`

gives you the inverse function. For example, `sin`

is `1○Y`

and `arcsin`

is `¯1○Y`

. So `11○Y`

extracts the imaginary part into a real number. `¯11○Y`

will “put back” a real number into its imaginary place:

```
¯11○3
```

0J3

Of course, it can’t restore the real part, as that was discarded. So… given our 2-element real-and-complex vector from above, how can we reconstitute our original `N`

? In other words, how can we convert `(2 0)(3 1)`

back to `2J3 0J1`

?

```
⊃+/¯9 ¯11○(2 0)(3 1)
```

2J3 0J1

If the argument is a matrix, we can use

```
N←2 2⍴2J3 0J1 10 0
m←9 11○⊂N
⊃¯9 ¯11+.○9 11○⊂m
```

┌────┬───┐ │ 2 0│3 1│ │10 0│0 0│ └────┴───┘

If you deal with complex numbers a lot, you might want to define `J←{⍺+0j1×⍵}`

which will then allow you to write `a J b`

to form `aJb`

, and so `⊃J/vec`

for this challenge.

Complex numbers are not just for hard-core mathematicians. Sometimes they are convenient to use as simple scalar 2D coordinates, where the real part represents offset along one axis, and the imaginary part along the other. One benefit in doing so is that some formulas become vastly simpler with this representation. Let’s say we have two points in 2D space, `(a,b)`

and `(x,y)`

, and we want to compute the distance between them. The traditional approach is something like this:

```
(a b x y)←4 6 1 2
0.5*⍨+/2*⍨a b-x y
```

5

Let’s rewrite it given `(u v)←4j6 1j2`

:

```
(u v)←4j6 1j2
|u-v
```

5

This lends itself nicely to a 2-train:

```
Dist←|-
u Dist v
```

5

Now imagine you need to represent some vectors in 2D space. `3j3`

would point north-east. We can now rotate the pointer 90 degrees counter-clockwise, with `0j1×3j3`

:

```
0J1×3J3
```

¯3J3

Now it points north-west instead. Using `0J¯1×`

will rotate clockwise instead. Also, multiplication by `¯1`

(which is `0J1*2`

) and so rotation by 180 degrees, giving us the oppositely pointed vector, and further multiplication by `0J1`

(i.e. to `0J1*3`

) is 270 degrees. This means we can get the four corners with `3j3×0j1*⍳4`

. Similarly, we can get the four cardinal directions with `3J0×0J1*⍳4`

:

```
3J3×0J1*⍳4
3×0J1*⍳4
```

¯3J3 ¯3J¯3 3J¯3 3J3

0J3 ¯3 0J¯3 3

Some more cheatsheet about vectors: `+v`

is reflection by x-axis, `+-v`

is by y-axis, `|v`

is length, `×v`

is unit vector in that direction, `k××v`

is vector of length `k`

in that direction. If you want to scale vector `v`

with scaling factor `k`

, do `k×v`

, and to rotate vector `v`

by the angle of vector `w`

, do `v××w`

.

You can represent a number of “moves” in 2D space as complex vectors, say `moves←1j2 0j3 ¯1j0`

. This means move 1 right and 2 up, then 3 right, then 1 down. Given such a moves sequence, where do we end up?

```
moves←1j2 0j3 ¯1j0
+/moves
```

0J5

What points did we pass through?

```
+\moves
```

1J2 1J5 0J5

Although we may want to say

```
+\0,moves
```

0 1J2 1J5 0J5

to include the origin.

Conversely, given a set of points, what is the corresponding moves sequence?

```
2-⍨/0 1J2 1J5 0J5
```

1J2 0J3 ¯1

Sometimes, it is convenient to deal with the angle (upwards from due east) and magnitude (pointer length) instead of the “coordinates”. We can already get the magnitude (absolute value) with `|Y`

but the angle (or phase) is `12○Y`

. Side note: the `12○Y`

is the one called `atan2()`

in other languages. Remember how convenient it was to use the scalar `○`

function with a 2-element left argument `9 11`

. For that same reason, `|Y`

exists as `○`

argument, which is 10 of course. So `10 12○Y`

gives you the magnitude and phase. Of course, we can use `10 12∘.○Y`

and `10 12○⊂Y`

like before.

How about the other way, if we have an angle and magnitude and want to combine them into a single complex number?
Remember how we used `{⍺+¯11○⍵}`

before. This is then `{⍺×¯12○⍵}`

(or, if you prefer, `¯10 ¯12×.○Y`

).