HarmonicVector Represents an interval in Harmonic Space


Inherits from: Object


A pitch interval can be represented as an integer vector, an n-tuple of integers in n-dimensional space. The base of the lattice consists of prime numbers up to the nth prime. For every interval ratio there corresponds an exponent vector of primes, which compose the numbers in the ratio.


For example, with n = 3, the base is [2, 3, 5], 

<0,0,0>  2**0,  3**0, 5**0 = 1/1

<-1, 1,0>  2**-1, 3**1, 5**0 = 3/2

<-4, 4, -1> 2**-4, 3**4, 5**-1 = 81/80


HarmonicVectors carry all the information pertaining to an interval and are made from either ratios or vectors. If made from vectors it assumes that the first dimension of the vector is 3 and calculates the corresponding value for the dimension of 2. This is called 'octave completion'. For ratios, the ratio given is the complete ratio and the octave reduced one is then calculated. 


HarmonicVectors are the elements of PitchSets. They are usefull for doing harmonic arithmetic and having  multiple representations for a single harmonic interval. For more on harmonic space, see James Tenney's "John Cage and the Theory of Harmony" (available at: http://www.plainsound.org/pdfs/JC&ToH.pdf)


See also: Dissonance, PitchSet 


This class requires a Vector class which is available in the VectorSpace quark.


Creation / Class Methods


*with (reduced)

Makes an instance of HarmonicVector from an octave-reduced vector, that is, a vector whose

prime power series starts at base 3 instead of 2. A reduced intervals is invariant with respect to octaves, correspoding to the psychoacoustic phenomenon of 'octave equivalence'. Ignoring octaves

in harmonic arithmetic can be quite useful as chromas are separated from register. 


reduced - An array of powers of primes. The highest primes base defined is 43, far above what is musically useful. If nil is given as the argument, it returns an HarmonicVector of [0], which is the ratio 1/1.  

g = HarmonicVector.with([2]); // 9/8, two fifths

useful information:

g.cents // octave reduced pitch distance

g.magnitude // distance to origin

g.harmonicDistance // City-block metric distance to origin (Tenney)

g.harmonicity // Weighted prime-bases measure (Barlow)

g.gradusSuavitatis // Degree of sweetness (Euler)

*from (ratio)

Makes an instance of HarmonicVector from a ratio. 

ratio - The ratio should be in the form of a [p,q] array.

HarmonicVector.from([1,1]);

HarmonicVector.from([3,2]);

HarmonicVector.from([5,6]);

HarmonicVector.from([7,6]);

HarmonicVector.from([14,11]); // this is represented by a 5 dimensional vector

Class Variables

base

This classvar is used for internal calculations. It is initialized up to prime 43 which is pretty much beyond human harmonic perception.

Instance variables 

A harmonic vector has the following attributes: 

vector

The complete integer vector of that interval, including the dimension of 2. It is a vector class and not an array or a number. 

reduced

The octave reduced vector, beginning from the dimension of prime 3.  

ratio

The calculated ratio, it is not octave reduced.

reducedRatio

The calculated octave reduced ratio.

pow2

This is used internally in calculations and corresponds to the ammount of octaves that have been reduced.

// example: 

g = HarmonicVector.with([-2,-1]);

g.ratio; // ratio: 1/45 

g.reducedRatio; // octave reduced ratio: 64/45

g.vector // the complete vector [2**6, 3**2.neg, 5**1.neg]

g.reduced // octave reduced vector (the input argument)

Working with arrays of HarmonicVectors


For making harmonic vectors from arrays, use the following added methods to Array:


g = [ [1,1],[16,15],[9,8],[6,5],[5,4],[4,3],[45,32],[3,2] ].asHvector;

g.do(_.postln); 

g = Array.fill(8, {[3.rand2,3.rand2,3.rand2]}).toHvector;

g.do(_.postln); 


katapykne

See the helpfile for numberExtras 

// example

g = HarmonicVector.from([16,15])

g.katapykne(4); 



magnitude

Magnitude of the vector in harmonic space. It is another kind of harmonic metric

g.magnitude;



complete

This method completes the octaves for a reduced ratio or vector. It is usually used under the hood when creating harmonic vectors. 



toRatio



toVector

adjustOctave



makeOperands (tis, tat)


+ (that)

Adding is an intervallic operation, that is, the addition of two harmonic vectors is equivalent to the product of their ratios. The addition is performed on the vectors, not the ratios. 

that - Another harmonic vector. If both have different dimensions, they will be made of the same size before the operation.

// example

g = HarmonicVector.from([5,4]);

h = HarmonicVector.from([3,2]);

g + h; // 5/4 + 3/2 = 15/8 

// (a maj third plus a fifth = a maj seventh)



- (that)

Subtraction is performed on the vectors, it is equivalent to subtracting the intervals, that is, to dividing their ratios. 

that - Another harmonic vector. If both have different dimensions, they will be made of the same size before the operation.

// example

g = HarmonicVector.from([2,1]);

h = HarmonicVector.from([10,9]);

g - h;



* (that)

I am not sure what this means musically. Actually I do: nothing. To multiply two vectors by multiplying each  two members of a dimension is not even defined properly for vector spaces, si this is an experimental method.  

that - Another harmonic vector. If both have different dimensions, they will be made of the same size before the operation.

// example

g = HarmonicVector.from([3,4]);

h = HarmonicVector.from([6,5]);

g * h



/ (that)

The same as above, with the addition that the results of division are even more perplexing than those of multiplication. Many combinations produce Division by Zero errors.

that - Another harmonic vector. If both have different dimensions, they will be made of the same size before the operation.

// example

g = HarmonicVector.from([2,1]);

h = HarmonicVector.from([3,2]);

g / h


** (scalar)

This one is useful: raising an interval to an integer power means adding it to itself in series. If the scalar is real you can obtain interesting experimental results.

scalar - an integer, although you can obtain interesting experimental results with fractions. 

// example

g = HarmonicVector.from([7,5]);

g ** 3;

g ** 1.25;

g = HarmonicVector.from([5,6]);

g ** 2;

g ** 1.5;

g ** 1.25;

cents (reduce = true)

Returns the cent value. 

reduce - If true, returns the cent value of  the reduced interval, otherwise the complete one.

isInIsland (unisonmatrix)

This method returns a boolean stating whether the vector lies inside a periodicity block (as defined by a unisonmatrix). It is used by PitchSet to separate its intervals into timbral and harmonic ones. See its help file for more info. 

g = HarmonicVector.from([7,4]);

g.isInIsland;

g = HarmonicVector.from([4,3]);

g.isInIsland;



Examples of harmonic arithmetic: 


a = HarmonicVector.from([4,3]); // a fourth

b = HarmonicVector.from([15,16]); // a just minor second below 1/1

c = HarmonicVector.from([64,45]); // a just higher tritone (Gb if 1/1 is C)

d = HarmonicVector.from([45,32]); // a just lower tritone (F# if 1/1 is C)

a - b; // the interval between the fourth and the semitone below is a higher tritone

c - b; // but between the tritone and the lower semitone there is a wolf fifth

d - b; // it forms a perfect fifth from the other tritone 

a ** 5; // a fourth raised to the fifth is a smaller semitone (imagine a series of fourths) 


// finding commas, execute line by line:


a = HarmonicVector.with([-2]); // 16/9 (a 3-limit minor seventh)

b = HarmonicVector.with([2,-1]); // 9/5 (a 5-limit minor seventh)

a + b // sum is a 5-limit minor sixth

a - b // difference between 16/9 and 9/5: inverted syntonic comma

b - a // difference between 9/5 and 16/9: a syntonic comma

// division and multiplication of harmonic ratios are very difficult to conceptualize:

a * b // Multiplication gives a Pithagorean minor sixth (why?)

a / b // Perfect fourth (also why?) 

b / a // Error: division by zero


(b - a).cents; // size of syntonic comma

(a + b).cents; 

1.addCents(813.6862).asRatio; 


(a * b).cents; // what does mult mean?

1.addCents(792.17999).asRatio; // a low sixth?

(a + b) - (a * b); // which is a syntonic comma away from the sum? Mult as a symmetric sum?


(a/b).cents; // and what about division? It gives a 4/3?


// the following is very interesting:

(a / b) * (b - a); // a fourth times a comma: a sixth lowered by a syntonic comma

(a / b) / (b - a); // fourth dividied by comma: unison! [its vector should be integer!]

(a / b) + a; // fourth plus a 3 limit min 7: pythagorean maj6

(a / b) + b; // fourth plus a 5 limit min 7: 5 limit min3

(a / b) * a; // fourth times a 3 limit min 7: a 3 limit second


(a * b) * (a / b); 

(a * b) / (b - a)



...

(c) 2008 jsl