Irken Kitties

Matrices as Linear Operators

Since they are my favourite, let’s learn something neat about matrices, something that can also serve as the first post on this new blog of mine about math, programming, and DSP.

Sonoluminescence

I wrote a new track called Sonoluminescence yesterday during one of my: “Make a song as fast as I can”, marathons. Took about 5 hours in total to write, plus maybe an hour mixing it. Writing music quickly works pretty well, and seems to bring out more creativity.

What is Sonoluminescence?

What is sonoluminescence anyway? Basically, they discovered it while working on sonar. Some researchers were trying to speed up the development of photographic film by shooting ultrasonic soundwaves at a flask of developer fluid (for some reason) and noticed the bubbles it was creating were emiting light.

Building My Shruthi-1

Last year I built a small MIDI controlled polyphonic synthesizer called KittySynth using a 72MHz LeafLabs Maple microcontroller board, an Audio Codec Shield from Open Music Labs, and some C++. I had originally had some ideas to try to build something like this by abusing the timers and PWM duty cycles on a 16MHz Arduino Mega I have, but quickly realized there was no way on earth I could build what I wanted to with the small amount of resources on an Arduino. The ARM based STM32 chip on the Maple had just enough resources available to create an 8-voice polyphonic wavetable synth, which I should write about sooner or later.

Anyway, while researching for that project I found out that someone actually has created a perfectly viable synthesizer based around a 20MHz ATMega chip (as in the Arduino) called the Shruthi-1. I thought this was a perfect opportunity to go through the steps of actually building a proper synth of the sort I would someday like to design, so I ordered the Shruth-1 4-Pole Mission Kit, and decided to put it together from scratch.

The Parts Arrived

Recreating the Haskell List Part 6: The IO Monad

This is part 6 of a 6 part tutorial

The IO Monad

In pure functional programming, all functions are supposed to be referentially transparent, and that means that each time you call a function with the same arguments, it should give you the exact same result. When functions are referentially transparent, you have a lot less worries about whether or not it will always work correctly.

A mathematical function is never going to give you a different answer no matter how many times you give it the same argument. The reason for that is pretty much that it cannot get any values from anywhere other than what you passed it, so it can never be any different.

Recreating the Haskell List Part 5: Monads

This is part 5 of a 6 part tutorial

Monads

The Haskell list type is also an instance of the Monad typeclass. There are four functions defined for a monad, but you only need to implement 2 of them: >>= (pronounced bind) and return.

The Monad Typeclass

1
2
3
4
5
class Monad m where
    (>>=) :: m a -> (a -> m b) -> m b
    (>>) :: m a -> m b -> m b
    return :: a -> m a
    fail :: String -> m a

The easiest function is return. It just wraps a value in the monad container, and it is exactly the same thing as pure from the Applicative class. The bind function takes a monad holding a value of type a, and a function which can change an a into the same type of monad holding something of type b.

Before making MyList an instance of Monad, it might be easier to see what happens if we make something simpler like Container from part 1 an instance first.

Making Container a Monad

1
2
3
4
5
6
instance Monad Container where
    (Container contents) >>= f = f contents
    return a = Container a
-- binding a container to a function
(Container 3) >>= (\x -> return $ x + 2)
=> Container 5

Recreating the Haskell List Part 4: Applicative Functors

This is part 4 of a 6 part tutorial

Applicative Functors

A Haskell list is also an Applicative Functor. If we want to make MyList one too, we can look at the interface for the Applicative class, and implement the right functions.

Interface for the Applicative Typeclass

1
2
3
4
:info Applicative
=> class (Functor f) => Applicative f where
    pure :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

So, it looks as though we need to implement the functions pure and <*> in order to be an instance of Applicative. This also says that whatever is Applictaive has the prerequisite of also being a Functor. The function pure must take any type a and wrap it in the container MyList. This is also called lifting a into the Functor. Implementing pure is easy enough, because it is the same thing as our data constructor, Cons.

Recreating the Haskell List Part 3: Monoids

This is part 3 of a 6 part tutorial

Monoids

It turns out that cons lists can be more than just a Functor, it can be a Monoid. A Monoid is a object with a single associative binary operation, and an identity element. This means that things like addition and multiplication form a monoid.

The identity element for addition is the number $0$, because $x + 0 = x$. An identity element and any other element, when operated on by the single associative binary operation, is one that does not change the other element. Basically you can add $0$ to any number and you just get the same number. The identity element for multiplication is $1$, because $x \cdot 1 = x$ for every number.

The binary operation should be one which can combine two of the objects, and for a list that happens to be appending them using the function ++.

[1, 2, 3] ++ [4, 5, 6] == [1, 2, 3, 4, 5, 6] Easy enough, so that means the identity element, the element you can combine with a list that will return the same list is: [], the empty list. [1, 2] ++ [] == [1, 2]

The ghci command :info shows that to be an instance of a monoid you must implement the functions mempty which returns the identity element, and either mappend or mconcat. Typeclasses can sometimes have default implementations for some functions, and it’s often the case that two functions are actually defined by default in terms of one another, meaning you only have to implement one of them and the other will automatically work. Here mappend and mconcat are defined in terms of each other so we just decide to implement the easier of the two, mappend

Looking at the type signatures below we can see mappend :: a -> a -> a, where in our case a will be the type MyList. This means mappend receives two lists and returns a third in which they are combined. For addition this would have been receiving two numbers that need to be combined, but for a list it just means to stick them together end to end.

Recreating the Haskell List Part 2: Functors

This is part 2 of a 6 part tutorial

Functors

How can we modify or transform a value or values that are contained in a data structure such as Container? Let’s say we have a Container holding the integer 4, and we want to add 1 to it. The problem is that a Container doesn’t have addition defined for it, and really, it shouldn’t considering that any possible type could be stored inside it, any number of which have no meaningful way to respond to addition.

Let’s look at a similar situation in C++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <class T>
class Container {
   T _value;
   public:
   Container(T value) : _value(value) { }
   T get_value() {
       return _value;
   }
   void set_value(T value){
       _value = value;
   }
};
Container<int> container = Container<int>(4);
//  Of course, you can't do this to transform the value inside
container = container + 1
//  You must remove it, apply the transformation and put it back
int x = container.get_value();
x = x + 1
container.set_value(x);

The extreme generality of this C++ class means that it would be a mistake to define operator+ on it, as any number of types T also cannot meaningfully respond to addition. Now we find ourselves in a similar situation in Haskell:

1
2
3
4
5
6
7
8
9
let container = Container 4
let container' = container + 1
<interactive>:3:28:
    No instance for (Num (Container Integer))
        arising from a use of `+'
    Possible fix:
        add an instance declaration for (Num (Container Integer))
    In the expression: container + 1
    In an equation for container': container' = container + 1

Recreating the Haskell List Part 1

This is part 1 of a 6 part tutorial

Data Structures as Containers

In a language like C, you can think of data structures as containers which hold one or more objects.

A Container

1
2
3
typedef struct int_container_t {
    int i;
} int_container_t;

The int_container_t type is now something which holds one int. To make the same sort of data structure in Haskell you would write:

Int container in Haskell

1
data IntContainer = IntContainer Int deriving Show

Ignoring for a moment the suffix deriving Show, this looks a lot like a function declaration, because that is essentially what it is. The identifier IntContainer appears on both sides, but the two are actually in two different namespaces. It is not necessary for these two identifiers to have the same name, but people will often do this by convention.

The left hand side of this declaration names a new type IntContainer, and the right hand side is defining a data constructor for this type, essentially a function named IntContainer which takes one Int as argument which it uses to create an instance of this type.

Using the data constructor in ghci

1
2
3
4
5
6
7
8
9
10
--  create an instance of IntContainer passing the value 4
IntContainer 4
=> IntContainer 4
--  Checking the type signature of the IntContainer data constructor function
:t IntContainer
=> IntContainer :: Int -> IntContainer
--  checking the type of an instantiated IntContainer
let i = IntContainer 4
:t i
=> i :: IntContainer

If I pass the data constructor a 4, it returns something which is of type IntContainer. The ghci command :t can be used to get type information about just about anything in Haskell. IntContainer :: Int -> IntContainer is read “IntContainer is a function which accepts an Int and returns an IntContainer”. i :: IntContainer is read “i is of type IntContainer”.

Consonant Intervals and Orthogonality

In this article I am going to explore some factors which are involved in the perception of consonance and dissonance of notes in the chromatic and major musical scales. The distance between two notes is called an interval, and there are 12 notes in the western chromatic scale. There are two common methods of calculating the frequencies of these notes.

Equal Temperment

The most common method used in modern times is called Equal Temperment. In this tuning, each adjacent note is related by the ratio of a 12th root of 2 or:

Starting from A 440hz and calculating each of the 12 notes of the chromatic scale up to the next A, looks like this:

Equal Tempered Note Frequencies
1
2
3
4
5
6
7
r = 2.**(1/12.0)
start_note = 440.0
1.upto(12).map {|interval| start_note *= r }
=> [466.1637615180899, 493.8833012561241, 523.2511306011974,
    554.3652619537443, 587.3295358348153, 622.253967444162,
    659.2551138257401, 698.456462866008, 739.988845423269,
    783.9908719634989, 830.6093951598906, 880.000000000000]