Fuzzy Logic

Fuzzy Logic is a system where a word can stand for a range of numbers. For example, fast may cover the range from 140-200 beats per minute. This is in contrast to crisp 'traditional' logic where fast would have a single value, say fast = 170 bpm. Not all numbers in the range are equal to the label (word) to the same extent, we say that they don't all have the same degree of membership. For example, while 170 is clearly a fast tempo, 140 is somewhat fast, and 190 is getting closer to very-fast than fast. This degree of membership is depicted as a triangle that covers the range along its flat bottom with a peak near the middle. The higher the triangle is at any location the more certain it is that this value describes the label. This triangular area, where a range of values represent a label, is called a fuzzy number.

A fuzzy set is a collection of fuzzy numbers, usually with overlapping regions. So the tempo of 145 bpm may be 'fast' to a small degree but also 'moderately-fast' to a large degree because there is an unclear, or fuzzy, boundary between these terms.

You may be able to imagine that the progression of tempi from slow to very fast is not an even one, it is typically more fine grained around the central values from moderatly slow to moderatley fast and more easily identified at the extremes of very slow and very fast. We say that such a progression is non-linear, that is it is uneven and, if drawn on a graph, would look like a wavy line. One of the uses for fuzzy logic is to generate such non-linear clurves without all the mathematical fuss and bother. This is done by describing a series of fuzzy numbers with overlapping boundaries and converting a linear input (1,2,3,4...) to a non-linear output (1, 3, 4, 4,...) by a processes oddly described as 'defuzzification.'

In order to enable this process jMusic includes a very simple fuzzy logic implementation. In the jm.music.tools.fuzzy package are two classes, FuzzyNumber and FuzzySet.

FuzzyNumber
This class describes a fuzzy number with a triangular membership function. Fuzzy numbers can be added to a fuzzy set. The number has three main properties, peak, minimum, and maximum, which describe the apex, left corner and right corner of the triangle. The triangle is normalised in the vertical direction, so membership values will be between 0.0 and 1.0. The degree of membership is computed by the getMembership() method.

FuzzySet
This class describes a fuzzy set that contains one or more fuzzy numbers. FuzzyNumber objects can be added to the set with the add() method. Defuzzification output uses the centriod scheme and is provided by the getOutput() method.

Example code: FuzztTest.java

View source

Lets have a look at an implementation of dynamic (loudness) variation using fuzzy logic.

import jm.music.data.*;
import jm.music.tools.fuzzy.*;
import jm.JMC;
import jm.util.*;

The fuzzy logic package must be included in the import statements.

public class FuzzyTest implements JMC {
FuzzyNumber pianissimo, piano, mezzoPiano, mezzoForte, forte, fortissimo;
FuzzySet dynamicSet;

public static void main(String[] args) {
new FuzzyTest();
}

The class is declared and instance vriables for various fuzzy numbers and one fuzzy set are created. The main method simply creates a new instance of the class.

    public FuzzyTest() {
dynamicSet = new FuzzySet();
pianissimo = new FuzzyNumber(0, 0, 40);
dynamicSet.add(pianissimo);
piano = new FuzzyNumber(20, 0, 55);
dynamicSet.add(piano);
mezzoPiano = new FuzzyNumber(35, 20, 65);
dynamicSet.add(mezzoPiano);
mezzoForte = new FuzzyNumber(50, 30, 95);
dynamicSet.add(mezzoForte);
forte = new FuzzyNumber(80, 50, 127);
dynamicSet.add(forte);
fortissimo = new FuzzyNumber(127, 100, 127);
dynamicSet.add(fortissimo);

The fuzzy set is created. Then each of the fuzzy numbers are created and added to the fuzzy set. The three arguments to the FuzzyNumber constructor are centre or peak value of the 'triangle', the minimum value, and the maximum value. Notice that the first and last numbers are triangles whose peak value is the same as either the min or max, meaning that they would appear perpendicular on one side rather than the normal ramp-up then ramp-down appearance. This is necessary because the extreme ranges of the dynamics (pianissimo and fortissimo) include the edge values of the jMusic dynamic range (0 and 127).

This has set up our fuzzy set. Now it's time to test it.

        for(int i=0; i<127; i++) {
for(int j=0; j<i; j++) {
System.out.print(" ");
}
System.out.println(".");
int out = (int)dynamicSet.getOutput(i);
for(int j=0; j<out; j++) {
System.out.print(" ");
}
System.out.println("+");
}

To show how the fuzzy set distorts the values going into it, like a look-up table does, we pass each value in a linear sequence to the set, from 1-127, and plot the output values from the set which you will see are not linear. The output is printed to the standard output of your Java system, i.e., the terminal. On this plot the dots (.) are the input values and the plusses (+) are the output values.

        +
           .
        +
            .
         +
             .
         +
              .
          +
               .
          +
                .
           +
                 .
           +
                  .
            +
                   .
            +
                    .
             +
                     .
              +
                      .

This shows that the fuzzy set can be used to covert the linear dynamic values into a more musical non-linear curve. The fuzzy set can be used just like a look-up table in this way, but specifying it is much more intuitive because it relates to 'normal' lingistic descriptions of the musical properties.


© 2004 Andrew Brown
jMusic Tutorial Index