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.
|