# Clojure Vector-2, Vector-3 & Vector-N

## Foreword

In this tutorial we will implement the vector functions that are used in other tutorials on this website. To be more exact: we will implement what is commonly known as **Vector2(x, y)**, **Vector3(x, y, z)** and **Vector4(x, y, z, w)** in other languages.

While we could implement **Vector2**, then **Vector3** and then **Vector4** functions we will simply make use of Clojure's functional nature and just go with **Vector-N** which will work with any dimension.

## Motivation

If you never heard about a Vector, it is a data structure that represents (for example) a monster's position in a game world. It has several components like **x**(the horizontal position) and **y**(the vertical position). If the monster lives in a 3D world then it also has a **z** component (the height).

## On Clojure's vector

As mentioned before, Clojure already has a vector data structure. We will make use of this data structure and simply create a few functions for things like vector multiplication, scaling, dot product, normalization and so on.

Clojure's vector looks like this:

`; define a vector with x=0 and y=1:`

(def u [0 1])

; define a vector with x=0 and y=1 and z=2:

(def v [0 1 2])

; access the components:

(nth u 0) ; x

(nth u 1) ; y

(nth u 2) ; z

The alternative would be a hash-map like this one:

`(def u {:x 0 :y 1})`

; access the components:

(:x u)

(:y u)

(:z u)

While this looks cool, it has the downside of not being dimension independent because we manually have to name the keys like **:x**, **:y**, **:z**, **:w** and so on. This would be a problem for something like **Vector-100**.

## Helper Functions

Our **vec-n** functions won't require any external libraries. We need a few very simple helper functions though:

`; calculates n²`

; (sqr 2) => 4

(defn sqr [n]

(* n n))

; (sqrt 9) => 3.0

; needed because (map Math/sqrt ...) doesn't work

(defn sqrt [n] (Math/sqrt n))

; (abs 3) => 3

; (abs -3) => 3

; needed because (map Math/abs ...) doesn't work

(defn abs [n] (Math/abs n))

## Required knowledge

### map

Before proceeding to the vector functions we will talk about the map function really quick. The common usage is like this:

`(map inc [1 2 3]) ; => (2 3 4)`

Where a function is **mapped** (in other words: applied) onto every element in the list.

Now **map** can also be used with multiple arguments, in which case it does what is known as **map and zip** in other languages:

`; other languages:`

(map (partial reduce +) (zip [1 2] [3 4]))

; => zip makes it ([1 3]

; [2 4])

; => + adds it to (4 6)

; in clojure:

(map + [1 2] [3 4]) ; => (4 6)

Or in other words: if we use map with multiple arguments then they are zipped together automatically. This is good because it keeps us from writing a lot of weird looking code.

*Note: since we usually want vectors as results, we often use mapv.*

### comp

Another function that we will use several times is the comp function. It creates function compositions like this:

`(def magic (comp sqr inc))`

; (magic 1) => 4 because (sqr (inc 1)) => (sqr 2) => 4

As we will see soon, **comp** allows us to write some complicated things in a very elegant way.

## Adding two Vectors

Alright, the first one will be easy. Given two vectors **u** and **v**, we will add together their components like this:

And here is how we do it in Clojure:

`; here is the easily readable version:`

; note: only works with 2 arguments

; (v+ [1 2 3] [1 1 1]) => [2 3 4]

(defn v+ [u v]

(mapv + u v))

; here is the better version:

; note: works with more than two arguments

; (v+ [1 2 3] [1 1 1]) => [2 3 4]

; (v+ [1 2 3] [1 1 1] [2 2 2]) => [4 5 6]

(def v+ (partial mapv +))

What happens is that map first zips together the components so we have

**([u.x v.x] [u.y v.y] [u.z v.z])**, then it adds them together because we used

**map +**.

The second version looks a bit weird, but it does exactly the same. The difference is that we created a function **comp**osition that works for more than two arguments.

## Subtracting two Vectors

This one will be even more easy. Given two vectors **u** and **v**, we will subtract their components from another like this:

And here is how we do it in Clojure:

`; again this is the easily readable version`

; note: only works with 2 arguments

(defn v- [u v]

(mapv - u v))

; and this is the better version:

; (v- [1 2 3] [1 1 1]) => [0 1 2]

; (v- [1 2 3] [1 1 1] [2 2 2]) => [-2 -1 0]

(def v- (partial mapv -))

The function works exactly like **v+**, just with a **minus**.

## Vector Equality

It gets even easier now. Two vectors are considered equal if their corresponding components are equal, or in other words: if **u.x==v.x** and **u.y==v.y** and so on. We use **==** instead of **=** to properly compare floating point values with a certain precision tolerance.

Here is the code:

`; the easier readable version:`

(defn v= [u v]

(every? true? (map == u v)))

; the version that works with >2 args

; (v= [1 2 3] [1 1 1]) => false

; (v= [1 2] [1 2] [1 2]) => true

(def v= (comp (partial every? true?) (partial map ==)))

Again the components are first zipped together by map, then they are compared with **==** so we get something like **[true true false]** if the **x** and **y** components were equal, but the **z** components were not. Afterwards the vectors are considered equal if the previous result contains only **true** values like **[true true true]**.

## Vector Length

Every vector has a certain length. By definition a vector like **[3 4]** is an arrow that points from the origin (which is **[0 0]**) to **[3 4]** like this:

Now the length of that arrow is exactly the length of the vector.

We calculate it like this:

For some computations we also want the squared length of that vector, so we will implement two length functions:

`; (v-len-sqr [1 2 2]) => 9`

(defn v-len-sqr [u]

(reduce + (map sqr u)))

; (v-len [1 2 2]) => 3.0

(def v-len (comp sqrt v-len-sqr))

Again we used **comp** here to express 'use **v-len-sqr** and then use **sqrt**' in a very elegant way.

## Scaling a Vector

There are two ways to scale a vector: either with another vector or with a so called scalar (which is a fancy word for a number):

So we could either write two functions: **v-scale-with-vector** and **v-scale-with-scalar** or we could write one function that handles both cases:

`; (v* [1 2 3] [2 2 2]) => [2 4 6]`

; (v* [1 2 3] 2) => [2 4 6]

; (v* 2 [1 2 3]) => [2 4 6]

(defn v* [u v]

(cond

(and (vector? u) (vector? v)) ; both are vectors

(mapv * u v)

(vector? u) ; u is a vector, v is a scalar

(mapv (partial * v) u)

(vector? v) ; v is a vector, u is a scalar

(mapv (partial * u) v)))

*Note: we called the function v*, however there is no real vector multiplication in mathematics. There are things like dot-product, cross-product and scale. And because scale is used very commonly, we will call it v* here.*

## Vector Distances

If we have two vectors then we can also calculate the distance between those two vectors. In the following picture the distance between **u** and **v** is exactly the length of the gray arrow between them:

Here is how we calculate it:

There are cases where we want the squared distance for our calculations, hence why we have two functions in Clojure again:

`; (v-dist [0 0] [1 1]) => 1.41`

; (v-dist [1 1] [4 2]) => 3.16

(def v-dist (comp v-len v-))

; (v-dist-sqr [0 0] [1 1]) => 2

(def v-dist-sqr (comp v-len-sqr v-))

Like in the above picture, the function first subtracts the components from each other by using our previously created **v-** function, then does the **square** and **square root** thing. Since we already did that in our **v-len-sqr** and **v-len** functions, we just reused them here.

And thanks to **comp**, this looks really elegant.

## Set the Length of a Vector

As mentioned before, by definition a vector is just an arrow that points from the origin (which is **[0 0]**) to some point. Sometimes we want to set the length of that arrow to something else, like shown in the following picture:

We can modify a vector's length by multiplying it with **'wished length / current length'**. For example if we have a vector **[0 1]** and want to set its length to **3** we do this:

We already have a function that calculates a vector's length, so the implementation is really easy in Clojure. However we want to take care of an edge case where the length of the vector **[0 0]** should be set. This case would cause a NullDivision error, so let's take care of it manually:

`; (v-setlen [0 1] 3) => [0.0 3.0]`

; (v-setlen [0 0] 1) => [1 0]

; (v-setlen [0 0 0] 1) => [1 0 0]

(defn v-setlen [u t]

(let [dim (count u)]

(if (every? (partial == 0) u) ; [0 0 ...]?

(into [t] (repeat (dec dim) 0)) ; [t 0 ...]

(v* u (/ t (v-len u))))))

This looks a bit weird, but it works. The if checks if **u** is a null vector like **[0 0 0]** (or **[0 0]** depending on the dimension), in which case it returns **[t 0 0]**, otherwise it changes the length of **u**.

## Normalize a Vector

Alright this one will be really easy again. Normalizing a vector means 'set its length to exactly 1'. We already have our **v-setlen** function, so let's just use it:

`; (v-norm [2 2]) => [0.70 0.70]`

; (v-norm [0 0]) => [1 0]

(defn v-norm [u]

(v-setlen u 1))

## Vector Dot Product

Almost done. The last thing we want to do is calculate the so called Dot Product like this:

And in Clojure:

`; (v-dot [1 2] [3 4]) => 11`

; (v-dot [1 3 -5] [4 -2 -1]) => 3

; (1*4 + 3*-2 + -5*-1 = 3)

(defn v-dot [u v]

(reduce +

(map * u v)))

As usual our **map** function zips together **u** and **v**, then it multiplies them because we used *. And in the end we sum up the results by using **reduce +**.

## Summary

Now we have a handful of vector functions that can be used with any dimension that we need. It will come in handy soon!