Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex numbers: new practice exercise #246

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
11 changes: 11 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,17 @@
"math"
]
},
{
"slug": "complex-numbers",
"name": "Complex Numbers",
"uuid": "0af9d842-762a-4054-b230-eaed7c0f937e",
"practices": [],
"prerequisites": [],
"difficulty": 5,
"topics": [
"math"
]
},
{
"slug": "armstrong-numbers",
"name": "Armstrong Numbers",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Instructions append

R supports complex numbers as a core type: for details see [here][complex1] and [here][complex2].
The purpose of this exercise is to implement them from scratch, _without_ using the built-in functions.

[complex1]: https://stat.ethz.ch/R-manual/R-devel/library/base/html/complex.html
[complex2]: https://www.cfm.brown.edu/people/dobrush/am33/R/intro/complex0.html
100 changes: 100 additions & 0 deletions exercises/practice/complex-numbers/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Instructions

A **complex number** is expressed in the form `z = a + b * i`, where:

- `a` is the **real part** (a real number),

- `b` is the **imaginary part** (also a real number), and

- `i` is the **imaginary unit** satisfying `i^2 = -1`.

## Operations on Complex Numbers

### Conjugate

The conjugate of the complex number `z = a + b * i` is given by:

```text
zc = a - b * i
```

### Absolute Value

The absolute value (or modulus) of `z` is defined as:

```text
|z| = sqrt(a^2 + b^2)
```

The square of the absolute value is computed as the product of `z` and its conjugate `zc`:

```text
|z|^2 = z * zc = a^2 + b^2
```

### Addition

The sum of two complex numbers `z1 = a + b * i` and `z2 = c + d * i` is computed by adding their real and imaginary parts separately:

```text
z1 + z2 = (a + b * i) + (c + d * i)
= (a + c) + (b + d) * i
```

### Subtraction

The difference of two complex numbers is obtained by subtracting their respective parts:

```text
z1 - z2 = (a + b * i) - (c + d * i)
= (a - c) + (b - d) * i
```

### Multiplication

The product of two complex numbers is defined as:

```text
z1 * z2 = (a + b * i) * (c + d * i)
= (a * c - b * d) + (b * c + a * d) * i
```

### Reciprocal

The reciprocal of a non-zero complex number is given by:

```text
1 / z = 1 / (a + b * i)
= a / (a^2 + b^2) - b / (a^2 + b^2) * i
```

### Division

The division of one complex number by another is given by:

```text
z1 / z2 = z1 * (1 / z2)
= (a + b * i) / (c + d * i)
= (a * c + b * d) / (c^2 + d^2) + (b * c - a * d) / (c^2 + d^2) * i
```

### Exponentiation

Raising _e_ (the base of the natural logarithm) to a complex exponent can be expressed using Euler's formula:

```text
e^(a + b * i) = e^a * e^(b * i)
= e^a * (cos(b) + i * sin(b))
```

## Implementation Requirements

Given that you should not use built-in support for complex numbers, implement the following operations:

- **addition** of two complex numbers
- **subtraction** of two complex numbers
- **multiplication** of two complex numbers
- **division** of two complex numbers
- **conjugate** of a complex number
- **absolute value** of a complex number
- **exponentiation** of _e_ (the base of the natural logarithm) to a complex number
19 changes: 19 additions & 0 deletions exercises/practice/complex-numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"colinleach"
],
"files": {
"solution": [
"complex-numbers.R"
],
"test": [
"test_complex-numbers.R"
],
"example": [
".meta/example.R"
]
},
"blurb": "Implement complex numbers.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Complex_number"
}
51 changes: 51 additions & 0 deletions exercises/practice/complex-numbers/.meta/example.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# function names are a bit wordy to avoid conflicts with those already in R

# is there something we can/should do with infix operators?

# tests for real values are quite repetitive, could this be improved?

create <- function(real, imag) list(real = real, imag = imag)

real <- function(z) z$real

imag <- function(z) z$imag

add <- function(z1, z2) {
if (is.numeric(z1)) z1 <- create(z1, 0)
if (is.numeric(z2)) z2 <- create(z2, 0)
list(real = z1$real + z2$real, imag = z1$imag + z2$imag)
}

subtract <- function(z1, z2) {
if (is.numeric(z1)) z1 <- create(z1, 0)
if (is.numeric(z2)) z2 <- create(z2, 0)
list(real = z1$real - z2$real, imag = z1$imag - z2$imag)
}

multiply <- function(z1, z2) {
if (is.numeric(z1)) z1 <- create(z1, 0)
if (is.numeric(z2)) z2 <- create(z2, 0)
list(
real = z1$real * z2$real - z1$imag * z2$imag,
imag = z1$real * z2$imag + z1$imag * z2$real
)
}

divide <- function(z1, z2) {
if (is.numeric(z1)) z1 <- create(z1, 0)
if (is.numeric(z2)) z2 <- create(z2, 0)
divisor <- z2$real^2 + z2$imag^2
list(
real = (z1$real * z2$real + z1$imag * z2$imag) / divisor,
imag = (z1$imag * z2$real - z1$real * z2$imag) / divisor
)
}

absolute <- function(z) sqrt(z$real^2 + z$imag^2)

conjugate <- function(z) list(real = z$real, imag = -z$imag)

exponential <- function(z) {
exp_a <- exp(z$real)
list(real = exp_a * cos(z$imag), imag = exp_a * sin(z$imag))
}
130 changes: 130 additions & 0 deletions exercises/practice/complex-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[9f98e133-eb7f-45b0-9676-cce001cd6f7a]
description = "Real part -> Real part of a purely real number"

[07988e20-f287-4bb7-90cf-b32c4bffe0f3]
description = "Real part -> Real part of a purely imaginary number"

[4a370e86-939e-43de-a895-a00ca32da60a]
description = "Real part -> Real part of a number with real and imaginary part"

[9b3fddef-4c12-4a99-b8f8-e3a42c7ccef6]
description = "Imaginary part -> Imaginary part of a purely real number"

[a8dafedd-535a-4ed3-8a39-fda103a2b01e]
description = "Imaginary part -> Imaginary part of a purely imaginary number"

[0f998f19-69ee-4c64-80ef-01b086feab80]
description = "Imaginary part -> Imaginary part of a number with real and imaginary part"

[a39b7fd6-6527-492f-8c34-609d2c913879]
description = "Imaginary unit"

[9a2c8de9-f068-4f6f-b41c-82232cc6c33e]
description = "Arithmetic -> Addition -> Add purely real numbers"

[657c55e1-b14b-4ba7-bd5c-19db22b7d659]
description = "Arithmetic -> Addition -> Add purely imaginary numbers"

[4e1395f5-572b-4ce8-bfa9-9a63056888da]
description = "Arithmetic -> Addition -> Add numbers with real and imaginary part"

[1155dc45-e4f7-44b8-af34-a91aa431475d]
description = "Arithmetic -> Subtraction -> Subtract purely real numbers"

[f95e9da8-acd5-4da4-ac7c-c861b02f774b]
description = "Arithmetic -> Subtraction -> Subtract purely imaginary numbers"

[f876feb1-f9d1-4d34-b067-b599a8746400]
description = "Arithmetic -> Subtraction -> Subtract numbers with real and imaginary part"

[8a0366c0-9e16-431f-9fd7-40ac46ff4ec4]
description = "Arithmetic -> Multiplication -> Multiply purely real numbers"

[e560ed2b-0b80-4b4f-90f2-63cefc911aaf]
description = "Arithmetic -> Multiplication -> Multiply purely imaginary numbers"

[4d1d10f0-f8d4-48a0-b1d0-f284ada567e6]
description = "Arithmetic -> Multiplication -> Multiply numbers with real and imaginary part"

[b0571ddb-9045-412b-9c15-cd1d816d36c1]
description = "Arithmetic -> Division -> Divide purely real numbers"

[5bb4c7e4-9934-4237-93cc-5780764fdbdd]
description = "Arithmetic -> Division -> Divide purely imaginary numbers"

[c4e7fef5-64ac-4537-91c2-c6529707701f]
description = "Arithmetic -> Division -> Divide numbers with real and imaginary part"

[c56a7332-aad2-4437-83a0-b3580ecee843]
description = "Absolute value -> Absolute value of a positive purely real number"

[cf88d7d3-ee74-4f4e-8a88-a1b0090ecb0c]
description = "Absolute value -> Absolute value of a negative purely real number"

[bbe26568-86c1-4bb4-ba7a-da5697e2b994]
description = "Absolute value -> Absolute value of a purely imaginary number with positive imaginary part"

[3b48233d-468e-4276-9f59-70f4ca1f26f3]
description = "Absolute value -> Absolute value of a purely imaginary number with negative imaginary part"

[fe400a9f-aa22-4b49-af92-51e0f5a2a6d3]
description = "Absolute value -> Absolute value of a number with real and imaginary part"

[fb2d0792-e55a-4484-9443-df1eddfc84a2]
description = "Complex conjugate -> Conjugate a purely real number"

[e37fe7ac-a968-4694-a460-66cb605f8691]
description = "Complex conjugate -> Conjugate a purely imaginary number"

[f7704498-d0be-4192-aaf5-a1f3a7f43e68]
description = "Complex conjugate -> Conjugate a number with real and imaginary part"

[6d96d4c6-2edb-445b-94a2-7de6d4caaf60]
description = "Complex exponential function -> Euler's identity/formula"

[2d2c05a0-4038-4427-a24d-72f6624aa45f]
description = "Complex exponential function -> Exponential of 0"

[ed87f1bd-b187-45d6-8ece-7e331232c809]
description = "Complex exponential function -> Exponential of a purely real number"

[08eedacc-5a95-44fc-8789-1547b27a8702]
description = "Complex exponential function -> Exponential of a number with real and imaginary part"

[d2de4375-7537-479a-aa0e-d474f4f09859]
description = "Complex exponential function -> Exponential resulting in a number with real and imaginary part"

[06d793bf-73bd-4b02-b015-3030b2c952ec]
description = "Operations between real numbers and complex numbers -> Add real number to complex number"

[d77dbbdf-b8df-43f6-a58d-3acb96765328]
description = "Operations between real numbers and complex numbers -> Add complex number to real number"

[20432c8e-8960-4c40-ba83-c9d910ff0a0f]
description = "Operations between real numbers and complex numbers -> Subtract real number from complex number"

[b4b38c85-e1bf-437d-b04d-49bba6e55000]
description = "Operations between real numbers and complex numbers -> Subtract complex number from real number"

[dabe1c8c-b8f4-44dd-879d-37d77c4d06bd]
description = "Operations between real numbers and complex numbers -> Multiply complex number by real number"

[6c81b8c8-9851-46f0-9de5-d96d314c3a28]
description = "Operations between real numbers and complex numbers -> Multiply real number by complex number"

[8a400f75-710e-4d0c-bcb4-5e5a00c78aa0]
description = "Operations between real numbers and complex numbers -> Divide complex number by real number"

[9a867d1b-d736-4c41-a41e-90bd148e9d5e]
description = "Operations between real numbers and complex numbers -> Divide real number by complex number"
39 changes: 39 additions & 0 deletions exercises/practice/complex-numbers/complex-numbers.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
create <- function(real, imag) {

}

real <- function(z) {

}

imag <- function(z) {

}

add <- function(z1, z2) {

}

subtract <- function(z1, z2) {

}

multiply <- function(z1, z2) {

}

divide <- function(z1, z2) {

}

absolute <- function(z) {

}

conjugate <- function(z) {

}

exponential <- function(z) {

}
Loading