Multidimensional Numbers Theory (MDNT)


Created by George Hara. Released under a Common Sense License.

You should also read about FLT.

The source code which implements this theory is included in the C# source code archive. QuickMdn is an application which allows you to quickly test various aspects of MDNT. The C# library is naturally implemented, that is, you can write for example "y = (1 + x / n) ^ n" to represent the natural exponentiation (at limit). All operations are implemented so as to require the minimum number of conversions between cartesian and polar coordinates. Fluogen is an application which transforms MDN equations to pictures.


The MDNT theory is an extension of the "Complex Number Theory (CXNT)".

A MDN is a multidimensional number, or multinumber.

MDNs exist in an Euclidean space.

Starting from a 3-dimensional space, basic math is generally asymmetric / distorted. Specifically, when using the higher dimensions, no rotation algorithm preserves the graphical symmetry exhibited by the rotation in a 2-dimensional space.

MDNs are associative and commutative, but are not distributive. Multiplication is not distributive over addition, except if the degree of the common MDN is maximum 2; x * (y + z) = x * y + x * z if dgr(x) <= 2. This is because this is a rotation in the 2D plane defined by x.

The lack of distributivity can be interpreted to mean that MDNs are true multidimensional numbers because they can't be decomposed, at least when having to switch between the cartesian and polar forms, so operations have to be performed over whole MDNs, as atomic operations over unsplittable blocks of coordinates, rather than over the separate components of each MDN. Unfortunately, this means that it's extraordinarily difficult to understand how to scale the operations from 1 and 2 dimensional spaces into a 3 dimensional space (and higher).

There is another reason why MDNs are true multidimensional numbers: the difference between the rotation of a solid object, that people are familiar with, and the MDN rotation. An MDN rotation is the rotation of a set of MDN points, in the entire multidimensional space, around the point of origin of the entire set.

Consider a book or other objects, larger or smaller, and rotate them. Rotate them in the 3D space. What are you actually doing? You are most likely rotating each object around an axis which goes through its middle, front to back or left to right. So, you're rotating 2D slices of the object, each around that middle axis, while at the same time moving the point of origin of each rotated slice so that it's along that middle axis, and you're also rotating the frame of reference in the direction of the object's rotation (this becomes clear when you're rotating diagonally). So, you've performed many 2D rotations in a 3D space, around various points of origin. So, you've not performed an MDN rotation, which in this case would be a 3D rotation in a 3D space, of each point of the object, around the point of origin of the entire object.

The 2D rotations in a 3D space are easy for people to visualize (in their mind) and perform because this is how the proximal reality works. For example, solid objects maintain their structure during rotations. These are valid operations in a 3D space, but they are not MDN rotations. Fluids and gases have no rigid structure to preserve, so their rotation is a bit different, although people can still visualize it to some extent.

People can visualize an MDN rotation for a point, but not for a set of points. Interestingly, it's exactly the fact that people can visualize solid object rotations that makes such rotations banal, whereas the fact that people can't visualize MDN rotations makes such rotations visually interesting (this is coming in Fluogen 2).

Polar form particularities

The chosen polar form allows the representation of an MDN using the minimum number of parameters, that is, equal with the number of dimensions and with the number of cartesian coordinates: a radius and D - 1 angles.

The polar form allows rotation to be independent from the number of dimensions. For example, in a 3D space, multiplying a point with itself can cause a rotation in the third dimension only if the point has a non-zero coordinate in the third dimension; if the third dimension coordinate is zero then its angle is also zero, so adding zero to itself is still zero.

The polar form allows rotation to be commutative, that is, it guarantees that the order in which the angles are rotated is irrelevant in generating a given cartesian form (= reaching the same point in space). Specifically, one angle is in the plane formed by the first two axes (X-Y), while the rest of the angles are along the rest of the axes (like XY-Z, XYZ-D4).

There are other ways of doing rotation, like rotating a point in each plane formed by every pair of axes, but this generates different cartesian forms, depending on the order of each plane rotation, that is, it's not commutative.

The first reduced angle of the polar form, the one between the first two axis has a value within [0, 2 * pi). This is to create a perfect extension of complex numbers, where the angle is within the same interval. The rest of the angles are within [-pi / 2, pi / 2].

In the MDNT there are many relational polar solutions for an equation. In a 2-dimensional space, each cartesian solution has 2 relational polar solutions; first: the "normal" solution; second: the radius is negative and the angle is added a Pi. For a D-dimensional space there are 2 ^ (D - 1) relational polar solutions, where the radius and all the angles have two choices (except the first angle which depends on all the other choices).

Interestingly, even if some angles are indeterminate, the number can still be determinate in cartesian form. This happens when the cartesians from two consecutive axes are 0; in this case, conventionally, the angle is represented as 0.

If an angle is ±90 degrees (plus its associated period), all lower-index cartesians are 0. This is easy to visualize in 3D, when the second angle (the one with the higher index) is 90 degrees. In this case, the first and second cartesians are 0.


D-dimensional space = A space with "D" dimensions.

Dimensions of z = Dim(z) is the number of axes used to make calculations. Dim(z) >= 2.

All axes of a multidimensional space, are perpendicular on each other, so they can not intersect.

Consider that:

d Î N{ >= 2 }.

p, r Î R.

x, y, z Î MDN{d} (D-dimensional space).

i, j are indexes of axes, i, j Î N{1...d}.

Di.r is the axis i of the number, with the value r (which is 1 by default).

cart[i] Î R. This is the value of the cartesian factor on the i axis. Instead cart it may be used a.

ang[i] Î R. This is the value of the angle on the i axis. Instead ang it may be used u.

Cartesian form

A MDN has a unique cartesian form, meaning that there is only one set of cartesian factors (= coordinates) that define the MDN:

z = cart[1], cart[2], ...., cart[d] = D1.cart[1] + D2.cart[2] + .... + Dd.cart[d].

Polar form

The polar form is the set of polar factors (radius and angles) that are associated to a cartesian form.

A MDN has multiple polar forms, meaning that there are multiple sets of polar factors that define the MDN.

The reduced polar form is the only set of reduced polar factors that define a cartesian form.

The relational polar form is formed by all sets of relational polar factors (in number of 2 ^ (d - 1)) that define a cartesian form.

The solution polar form is formed by all sets of solution polar factors that define a cartesian form (this is the relational polar form plus the periods of each angle).


There is only one set of partial reduced radiuses that define a MDN.

All reduced radiuses are positive.

The partial reduced radius of z on the i axis: radp_red[i] = abs(sqrt(sum{j = 1...i}(sqr(cart[j])))).

Equivalences: radp_red[1] = cart[1].

The reduced radius of z is rad_red = rad = radp_red[d].

The relational radiuses of z are rad_rel = +-rad_red.

The radius is also called magnitude.


There is only one set of reduced angles that define and MDN:

If cart[1] >= 0, ang_red[1] = asin(cart[2] / radp_red[2]) or atan(cart[2] / radp_red[1]) or acos(cart[1] / radp_red[2]).

If cart[1] < 0, ang_red[1] = asin(cart[2] / radp_red[2]) + pi or atan(cart[2] / radp_red[1]) + pi.

ang_red[i, i = 2...d - 1] = asin(cart[i + 1] / radp_red[i + 1]) or atan(cart[i + 1] / radp_red[i]).

If radp_red[i] = 0, the angle is indeterminate (it can have any value).

Here asin() and atan() have their domain: [-pi / 2, pi / 2].

In code, atan is is replaced with atan2, which takes the divided numbers as separate parameters. This allows, for example, to return a 0 angle when both parameters are 0.

The reduced angles have their domain:

ang_red[1] Î [0, 2 * pi).

ang_red[i, i = 2...d - 1] Î [-pi / 2, pi / 2].

Relational angles

Relational angles depend on each other to define a MDN.

There are 2 ^ (d - 2) sets of relational angles for a MDN. The first angle is determined from the rest.

Each relational angle must be:

ang_rel[1] Î [0, 2 * pi).

ang_rel[i, i = 2...d - 1] Î [-pi / 2, 3 * pi / 2].

Solution angles

There are an infinite number of sets of solution angles for a MDN: ang_sol[i] = ang_rel[i] + 2 * pi * k[i], where k[i] Î Z.

Generating the relational form

To generate the relational form of a MDN you have to choose between 2 possible cases (for each factor: the radius, all angles with index [2...d - 1]). The first angle is calculated from the radius and all other angles because it influences only the first 2 trigonometric factors, so this is the easiest way to do it.

Set z.rad_rel

With +z.rad_red then sign = 1.

With -z.rad_red then sign = -1.

If sign = 1 then z.ang_rel[i, i = d - 1...2] =

Choose z.ang_red[i] then sign = 1.

Choose pi - z.ang_red[i] then sign = -1.

If sign = -1 then z.ang_rel[i, i = d - 2...2] =

Choose pi + z.ang_red[i] then sign = 1.

Choose -z.ang_red[i] then sign = -1.

If sign = 1 then z.ang_rel[1] = z.ang_red[1].

If sign = -1:

If z.ang_red[1] < pi then z.ang_rel[1] = z.ang_red[1] + pi.

If z.ang_red[1] >= pi then z.ang_rel[1] = z.ang_red[1] - pi.

Trigonometric factors

z.trig[1] = multiply{i = 1...d - 1}(cos(z.ang_red[i])).

z.trig[j, j = 2...d - 1] = sin(z.ang_red[j - 1]) * multiply{i = j...d - 1}(cos(z.ang_red[i])).

z.trig[d] = sin(z.ang_red[d - 1]).

Generating the cartesian form from the polar form

cart[i, i = 1...d ] = rad_red * trig[i].

Mathematical functions

A multidimensional space closes within itself, meaning that the results have the same number of dimensions.

In more than 2 dimensions, the reverse method (of a method) does not necessarily lead to the initial number. Example: Mpf y = x.Sqr(); y = y.Sqrt(): y is not necessarily equal with x. Still, if before Sqrt() you set a particular solution form (you have to find it manually) of y, x would result. In this simple case, you do get " y ~== x", but in more complex cases (where conversions between polar and cartesian forms are being made) this would not always happen.


dgr(x) is the number of axes above which all cartesian factors are 0.

If a[i, i = 1...d] = 0 then dgr(x) = 0.

If a[i, i = dg, dg Î {1, d}] <> 0 and a[i, i = dg + 1...d] = 0 then dgr(x) = dg

The degree G is very important because a MDN with a degree smaller than the number of dimensions D of the MDN works exactly like a MDN whose number of dimensions is G.

This means, for example, that all operations on a scalar (a one dimensional number) work exactly as if they were applied on a MDN with a million dimensions and a degree of 1. Exceptions are operations which perform specific actions in superior dimensions, like rotations in a plane.


ord(x) is the number of axes below which all cartesian factors are 0.

If a[i, i = 1...d] = 0 then ord(x) = 0.

If a[i, i = or, or Î {1, d}] <> 0 and a[i, i = 1...or - 1] = 0 then ord(x) = or

While this definition may sound backwards, it doesn't depend on the number of dimensions.


pol(x) is the form of a MDN where the radius is (positive) 1.

x.cart[i] = x.cart[i] / x.rad = x.trig[i]


x.cart[i] = -x.cart[i]


inv(x) = 1 / x = 1 / x.rad * (x.trig[1] - x.trig[2] - .... - x.trig[d])


x, y Î MDN{d} are equal if each cartesian factor is equal: x.a[i] = y.a[i]


This operation represents the translation of a point.

(x + y).cart[i, i = 1...d] = x.cart[i] + y.cart[i]


This operation represents the translation of a point.

(x - y).cart[i, i = 1...d] = x.cart[i] – y.cart[i]


This operation represents the rotation of a point.

(x * y).rad = x.rad * y.rad.(x * y)

ang[i, i = 1...d - 1] = x.ang_rel[i] + y.ang_rel[i]


This operation represents the rotation of a point.

(x / y).rad = x.rad / y.rad

(x / y).ang[i, i = 1...d - 1] = x.ang_rel[i] – y.ang_rel[i]

(PR) Power, real

(x ^ p).rad = x.rad ^ p

ang[i, i = 1...d - 1] = x.ang_rel[i] * p

Natural exponentiation

Here, E = D1.e = e.

(E ^ x).rad = e ^ x.cart[1]

(E ^ x).ang[i, i = 1...d - 1] = x.cart[i + 1]

Although no mathematical proof is present, calculations show that E ^ x = lim{ N -> Inf }(1 + x / N) ^ N just as it is for e. However, even though for d = 2 we have E ^ x = 1 + sum{i = 1...Inf}( x ^ i / i!), for d >= 3 this is no longer true. This suggests that the formula for natural exponentiation is correctly chosen.

As you may see, despite what you might expect, the radius of the result is not e ^ sum{i = 1...d}x.cart[i]. It appears that the radius of e ^ Di.x.cart[i, i = 2...d] is 1.

What's most interesting in this formula is the fact that the cartesian system of coordinates directly translates into the polar system of coordinates.

Natural logarithm

ln(x).cart[1] = ln(x.rad)

ln(x).cart[i, i = 2...d] = x.ang_sol[i - 1]

This is the inverse formula of natural exponentiation, so its mathematical proof depends on the mathematical proof of natural exponentiation.

Generic logarithm

Correct for 2 dimensions.

log{y}(x) = ln(x) / ln(y)

log{y}(x) = D1 / log{x}(y)


Correct for 2 dimensions.

x ^ y = E ^ (y * ln(x))

Sin / Cos

Correct for 2 dimensions.

E ^ D2.u = D1.cos(u) + D2.sin(u) = pol(x)

E ^ D2.(-u) = D1 / E ^ D2.u = D1.cos(u) - D2.sin(u) = 1 / pol(x)

=> Sin: sin(u) = (pol(x) - 1 / pol(x)) / D2.2

=> Cos: cos(u) = (pol(x) + 1 / pol(x)) / D1.2

For more dimensions, the (unsolved) problem is defining what the sine and cosine of a MDN represent.

Let's consider what the sine of a real number is. The real number is an angle (so a one dimensional number), and the sine is a circle with a radius of 1 (so two dimensional number) obtained by going through all the values of the angle. By extension, this means that the sine of a MDN (with D dimensions) is a multidimensional sphere with a radius of 1 (and D + 1 dimensions) obtained by going through all the values of the cartesians of the MDN, cartesians which are used as angles.

This means that:

sin(x).rad = 1

sin(x).ang[i, i = 1...d] = x.cart[i]

You can see that this is very similar to exponentiation, except that the first cartesian is not the radius.

The problem of this operation is that it increases the number of dimensions (at every iterated application), whereas for sine in 2D it doesn't happen.

A potential constraint is: sin(x)^2 + cos(x)^2 = 1. This means that, no matter the number of dimensions, the equation always represents a multidimensional sphere with a radius of 1.

Distributive multiplication

There is a way to have a multiplication algorithm which is distributive over adding, and is also commutative: decomposed multiplication.

Here is an example: x * y = (D1.x1 + D2.x2 + D3.x3) * (D1.y1 + D2.y2 + D3.y3) = (D1.x1 * D1.y1 + D2.x2 * D1.y1 + D3.x3 * D1.y1) + (D1.x1 * D2.y2 + D2.x2 * D2.y2 + D3.x3 * D2.y2) + (D1.x1 * D3.y3 + D2.x2 * D3.y3 + D3.x3 * D3.y3)

As you can see, the multiplication between x and y is made by decomposing x and y in their cartesian factors instead of using the polar coordinates. The only thing that we need to clarify is what it means to multiply an axis with another (Di.xi * Dj.yj). We choose the multiplication as follows (here, the axes indexes are [0...d) not [1...d] as usual):

If i + j < d, Di.xi * Dj.yj -> the cartesian factor for the aixs with the index i + j is xi * yj.

Else Di.xi * Dj.yj -> the cartesian factor for the aixs with the index i + j - d is -xi * yj.

The decomposed multiplication represents the rotation of the system of reference, that is, one axis becomes another. In the case of the polar multiplication (based on the polar form), the multiplication represents the rotation of a point.

This operation has a problem as well: it depends on the number of dimensions. For example (D1.x1 + D2.x2) * (D1.y1 + D2.y2) in MDN{2} and (D1.x1 + D2.x2 + D3.0) * (D1.y1 + D2.y2 + D3.0) in MDN{3} give different results.

There are other ways to do distributivity, even without problems, but none of them preserves the graphical symmetry exhibited by the normal polar multiplication.

It should be noted that multiplication should be defined as the rotation of a point, so a random algorithm labeled "multiplication" is not enough.