Sunday, June 17, 2012

Edgeland sports fields

Elements of the Dutch landscape - 5

There are always sport fields at the boundary between city and country. Probably the optimal combination of low land costs and acceptable distance from the city. They are often near allotment gardens and are always threatened by budget cuts and land grabs.

They are difficult to find by car, because there are no orientation points nearby. They are not in the middle of nowhere, but on the edge of nowhere.

The components are always the same: parking lot, fence, gate, canteen, benches, light masts, fields, goalposts, flags, advertisements of local sponsors.

Extremely functional architecture. Almost acceptable  coffee, standard candy bars, friendly and enthusiastic staff. Positive atmosphere.

Montfoort
Schoonhoven
Hazerswoude
Rotterdam
Dordrecht

Wednesday, June 13, 2012

Old news experiment - 2

Last year I found a temporary source of free high quality newspapers. They were a few weeks out of date but that was no problem. Unfortunately the source has since dried up. But I still have a few left and I use them for self-experimentation. Like in: Fragen eines lesenden Arbeiters.

Borges quote - During WW-II Jorge Luis Borges did not want to read the "common" newspapers with all the war news. He did not find it culturally relevant and did not want to be distracted by this "noise". Instead he decided to read the classic literature about the Punic (?) wars.
Yesterday I spent a lot of time on Google but I could not find the source of the quote. It may have come from the book "Seven Nights" (no it didn't - I leafed through the whole book).

Research questions - With the thin stack of year-old newspapers in front of me it's difficult to formulate the research questions:
  • What news is still interesting after one year? Does it add a missing puzzle piece to my picture of the world? Does it stabilize my world view? (very subjective!)
  • What news is still relevant after one year? Does it show a relevant trend? Can and should I act on this news?
  • Is it useful to read the newspapers? Or can I spend my time better?
Detailed results - It takes about 2 hours of breakfast time (with tea and cake and laptop) to work through 4 quality newspapers. Most of the time is spent scanning headlines. A few articles are worth digging deeper. I've cut out 5 pages to keep. These are the main points:

Economics trends:
  •  Higher oil prices are bad for aircraft companies - America wants to use strategic oil reserves - More work is needed to pump oil from old wells - Dispute about levels of Saudi oil reserves after a cable on WikiLeaks.
  • More energy security through European gas pipeline network.
  • Threat of inflation in Europe - Fear of inflation in America.
  • Gold has never been so expensive - Investors are interested in Zimbabwe (platinum, diamonds, gold, chromium) and Mongolia (gold, silver, copper, lead, iron, uranium, coal).
  • Moody's downgrades Greek debt to B1 - Athens is angry.
  • Mervyn King sharply criticizes the bonuses of bankers.
  • China is afraid of inflation and rising prices - The four problems of China: high cost of housing, inflation, unjust income distribution, corruption - China spends more on the internal security apparatus than on the military - Social unrest is growing.
  • S&P has downgraded German banks because the state will likely not support them - German banks have loaned 37 billion to American municipalities and these are in financial problems.
  • Maersk has built the biggest container ship that can carry 18.000 containers.
  • Paul Krugman: What's happening in Wisconsin is, instead, a power grab - an attempt to exploit the fiscal crisis to destroy the last major counterweight to the political power of corporations and the wealthy. The shock doctrine is on full display.
Economic details:
  • Insider case against hedge fund manager Raj Rajaratnam.
  • Coca Cola it striving for more sustainability in the company.
  • Dutch Rabobank has survived the crisis well.
  • There is doubt if the Renault employees were really involved in espionage for China.
  • The creditors of Parmalat want more money.
  • The interest on the Irish debt might be reduced.
  • Credit Suisse might have supported American tax flight.
  • Glencore is a secretive commodities trading empire.
Information technology:
  • Every day web 10.000 pages link to Facebook - Facebook is becoming a closed "Internet inside the Internet".
  • Skype going into video-telephony and advertisement.
  • IPads and apps are hot.
  • Cloud computing "will give IT wings".
  • Computer industry desperately needs professionals.
  • Advertisers pay well for the chance to be linked to female bloggers - dooce.com has 100.000 followers.
  • What role did modern media play in the Arab spring? They are important, but not more than that.
Sociology:
  • The current religious crisis is different from the previous ones because this time we are totally uninterested in the question of God, we believe we can abolish any concept of God (Erkenntnis die: Wir koennen uns nicht fassen. / Und finden keinen der uns Goettern gleicht. / Und keinen, der uns hilfe reicht. / Wir sind uns ohne Gnade ueberlassen. - Guenter Kunert) - The SPD wanted to remove the crucifix from the meeting room of local parliament.
  • Eugenics under Franco in Spain, stealing the children of potential communists.
  • The British first heartily cooperated with Gadaffi and now they want to topple him.
  • 7.5 million Germans are "functionally illiterate", they can read short sentences but not longer texts, they cannot fill out a form, men: 60%, women 40%.
Culture:
  • Letters of Hans Fallada have been found in the Israeli national library. He writes about his loneliness, his illness and his fears. (Jeder stirbt fuer sich allein.)
  • The attack of the populist government on "elite" culture and "leftist hobbies" in the Netherlands.
  • A book was published on the letters of Bruce Chatwin.
Science:
  • With more cheap digital weather stations the temperature levels are being reported in tenths of degrees (like: 0.2), this precision is totally useless.
  • SkySails could reduce energy consumption in shipping.
  • Scientists did not distort climate data, US inquiry finds.
  • Watson, the computer, won the world "jeopardy" championship, humans do not mind very much.
Analysis - The collection above is heavily biased. It is strongly filtered in several steps:
  • Most of the things that happen in the world go unobserved and unreported.
  • The reported news is selected by the media corporations and news editors - they select what their readers want to pay for.
  • From the published news I select what I find remarkable, interesting or valuable - most probably I'm extremely biased and I'm searching for news that supports my general world view - it is easy to deduce my world view and political orientation from my selection above.
How much direction does the information give me - is there any actionable information?
  • I cannot do anything about the economic information. I can watch the trends unfolding but I'm unable to influence them. I cannot hide - as one of the 99% I'm too late to buy gold, and these times are too unpredictable to invest in anything. I could invest in a fund using a broadly spread portfolio but I'm unable to predict how close we are to bottom.
  • I can (and do) watch the sociological, cultural and scientific trends with interest, but again because these are emergent properties of society I can do relatively little about them. Governments were and are rotten. I will vote carefully in any next election, but will that help?
  • I see the direction the IT field is taking and it is useful to gain knowledge in that area. But I already know and do that.
Preliminary conclusion - working hypothesis
  1. Reading a year old newspaper does not differ much from reading a current newspaper.
  2. Most of the information is short term noise.
  3. Most of the long term trends are already known.
  4. Very little information is actionable.
  5. Most of the news amplifies feelings of insignificance and powerlessness.
  6. It is possible to find solace in culture and art.
  7. It is better to not read the newspapers at all or to concentrate on art and culture.
This is a much more negative conclusion than I expected! I don't know if I completely agree with myself and if I'm willing to follow-up on this conclusion. More thinking and experimenting to be done!

Sources:
Frankfurter Allgemeine Zeitung - 1,7,8 March 2011
International Herald Tribune - 26-27 February 2011
Guenter Kunert
Fragen eines lesenden Arbeiters

Monday, May 28, 2012

Sonification - sound of sand - 10

Curvature - I have used two different algorithms to determine the curvature of a shape.

Algorithm 1 - I cannot find the original article where I found the idea (I'm very sorry) but the principle is very simple:
And if we apply the algorithm to our test shape we get the following curvature estimate. This is not bad at all:
It is easy to see that the curvature is high in the corners and low in the straight edges. Also curvature is higher in the sharp corners. But the algorithm is not very precise.

Algorithm 2 - A better algorithm is given in the following article: Estimation of discrete curvature based on chain-code pairing and digital straightness (Shyamosree Pal, Partha Bhowmick, 2009). The algorithm applied to our test shape looks like this. It is much more precise and selective:
Sonification in the frequency domain - In the following sonifications you hear curvature algorithm 1 in the left channel and curvature algorithm 2 in the right channel. They are correlated but have different characteristics.
In the sonification we mapped the curvature values to the frequency domain. Below you see the spectrum of the star-shape sonification. Top channel is algorithm 1, bottom is algorithm 2. It is easy to see the points of the 6-pointed star:
 And our set of test shapes sound like this. Watch your ears and speakers - turn the volume down low!

mp3 - 01 circle - Algorithm 1 generates a lot of artifacts. Even a one pixel difference in arc-length is audible. That's why you hear the circle in the left channel. Algorithm 2 is much more precise and you hear hardly anything. In theory a circle should have a constant curvature, so both tones should be constant. But the pixellation disturbs this ideal. The result is more interesting than one would expect.

mp3 - 02 triangle - You can clearly hear the three points of the triangle. Algorithm 1 has some problems with diagonal lines. It is very sensitive to pixellation.

mp3 - 03 square - As is to be expected this is quite boring. Almost nothing happens. Only the four vertices cause some change in the sound.

mp3 - 04 star - Quite interesting to listen to. You can clearly hear the 12 vertices of the 6-pointed star.

mp3 - 05 horizontal rectangle - Is almost identical to the square.

mp3 - 06 random shape - Is approaching experimental musicality. Could be useful.


from Nsound import *
import math
debug1 = False
debug2 = False
debug3 = False
def convert_chaincode_to_x(c,x):
    if c == 1 or c == 0 or c == 7: x = x + 1; return (x)
    elif ( c == 2 or c == 6): x = x; return (x)
    else: x = x - 1; return (x)
def convert_chaincode_to_y(c,y):
    if c == 1 or c == 2 or c == 3: y = y + 1; return(y)
    elif c == 4 or c == 0: y = y; return(y)
    else: y = y - 1; return(y)
# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_xy_lists(filename):
    infile = open(filename)
    instr = infile.read()
    infile.close()
    if debug1: print instr
    # parse the input file - split it into words
    inwords = instr.split(' ')
    if debug1: print inwords
    # delete anything except the chain code
    i = 0
    for str in inwords:
        if str.find('0E+0') > -1 :
            break
        i = i + 1
    inwords = inwords[i+2:len(inwords)-1]
    if debug1: print inwords
    # fill the x and y lists with the chaincode values
    b_x_chaincode = list()
    b_y_chaincode = list()
    x = 0; y = 0
    for str in inwords:
        c = int(str)
        x = convert_chaincode_to_x(c,x)
        b_x_chaincode.append(x)
        y = convert_chaincode_to_y(c,y)
        b_y_chaincode.append(y)
    return(b_x_chaincode, b_y_chaincode)
# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_chaincode_list(filename):
    infile = open(filename)
    instr = infile.read()
    infile.close()
    if debug1: print instr
    # parse the input file - split it into words
    inwords = instr.split(' ')
    if debug1: print inwords
    # delete anything except the chain code
    i = 0
    for str in inwords:
        if str.find('0E+0') > -1 :
            break
        i = i + 1
    inwords = inwords[i+2:len(inwords)-1]
    if debug1: print inwords
    # fill the chaincode list with the chaincode values
    l_chaincode = list()
    for str in inwords:
        c = int(str)
        l_chaincode.append(c)
    return(l_chaincode)
def convert_xy_frequency(xy, minxy, maxxy, minf, maxf):
    r = float(maxf - minf)/float(maxxy - minxy)
    f = (xy - minxy)*r + minf
    return (f)
def sine_duration_frequency(duration, frequency):
    g = Generator(44100.0)
    length = math.ceil(float(duration) * float(frequency))/float(frequency)
    return g.drawSine(length, frequency)
# ==============================
directory = "C:\\Users\\user\\Documents\\shape\\shape\\"
filename = "06 random shape"
extension = ".chc"
# read file into xy lists
list_x, list_y = read_chc_file_to_xy_lists(
    directory + filename + extension)
# calculate curvature by arc length
list_c1 = list()
k = max(3,int(0.1*math.sqrt(len(list_x))))
for i in range(len(list_x)):
    ia = (i-k)%len(list_x)
    ib = (i+k+1)%len(list_x)
    dx = list_x[ia]-list_x[ib]
    dy = list_y[ia]-list_y[ib]
    dxy2 = dx*dx + dy*dy
    dxy = math.sqrt(dxy2)
    curv = (2*float(k) / dxy)
    if debug2:
        print list_x[i], list_y[i], round(curv,2)
    list_c1.append(curv)
# read file into chaincode list
list_c = read_chc_file_to_chaincode_list(
    directory + filename + extension)
# calculate curvature by chaincode pairing and digital straightness
list_c2 = list()
k = max(4,int(0.3*math.sqrt(len(list_x))))
for i in range(len(list_c)):
    di = float(0)
    for j in range (1,k):
        ia = (i+j)%len(list_c)
        ib = (i-j+1)%len(list_c)
        dj = abs(list_c[ia] - list_c[ib])
        dj = min(dj, 8-dj)       
        iap1 = (i+j+1)%len(list_c)
        ibp1 = (i-j+1)%len(list_c)
        djp1 = abs(list_c[iap1] - list_c[ibp1])
        djp1 = min(djp1, 8-djp1)       
        iam1 = (i+j)%len(list_c)
        ibm1 = (i-j)%len(list_c)
        djm1 = abs(list_c[iam1] - list_c[ibm1])
        djm1 = min(djm1, 8-djm1)
        di += min(min(dj,djm1),djp1)
    di = float(di)/k
    if debug3:
        print list_x[i], list_y[i], round(di,2)
    list_c2.append(di)
soundpixel_length = 0.02
min_f = 120.0
max_f = 3000.0
# generate a frequency modulated x signal
b_x_long = Buffer()
min_x = min(list_c1)
max_x = max(list_c1)
for x in list_c1:
    frequency = convert_xy_frequency(x, min_x, max_x, min_f, max_f)
    b_x_long << sine_duration_frequency(soundpixel_length, frequency)
b_x_long.normalize()
# generate a frequency modulated y signal
b_y_long = Buffer()
min_y = min(list_c2)
max_y = max(list_c2)
for y in list_c2:
    frequency = convert_xy_frequency(y, min_y, max_y, min_f, max_f)
    b_y_long << sine_duration_frequency(soundpixel_length, frequency)
b_y_long.normalize()
# code the x and y signal into the left and right channel of an audio stream
# write the audio stream into a .wav file
a = AudioStream(44100.0, 2)
a[0] = b_x_long
a[1] = b_y_long
a.writeWavefile(directory + filename + "_freq_curv" + ".wav")


Sunday, May 27, 2012

Three exciting lectures

Normally I find it cheap and easy to post a few links without further comments. But these three lectures fit my my current interests and emotions perfectly. So I hope they'll inspire you as much as they inspired me.

A romantic, melancholic, homesick artwork in cyberspace
Living and evolving algorithmic entities that shape our world
A historic view of information overload

Saturday, May 26, 2012

The flaming sun

Elements of the Dutch landscape - 4

Many years ago I became aware of the angry flaming sun while walking in Maastricht. This one was not so angry, more pensive and melancholic. Last year I saw that the sun was still there. It's even on google street view. Notice how one of the sun faces has been blurred (modern technology meets ancient symbol). 
Maastricht
Once I was sensitized I now see the symbol everywhere. On each of our walks I see it at least once. Why is such an ancient symbol so popular in the modern suburbs? Is it an archetype that cannot be suppressed?
I looked at a few websites for the symbolism and it's exactly as one would expect:
  • The sun stands for: truth, light, fertility, vitality, passion, healing, (male) vigor, agressiveness, power, force and leadership, dignity, courage, creativity, knowledge, self hood, life-source, re-birth, reincarnation, immortality.
  • The sun face protects from evil powers and influences.
  • The combination of the sun and the moon stands for the sexual and spiritual union of a male and a female.
Still I wonder if the people who hang these on their garden sheds and near their doorbells realize this consciously. My private pet theory is:
  • Our modern culture has banished all elements it considers irrational or primitive, especially: magic, superstition, religion and symbolism.
  • Our modern architecture has banished all ornamental elements and details. It is functional and bland.
  • But somehow we cannot live without irrationality and ornamentation. So the banished elements crop up in unexpected places.
Modern garden-variety examples (literally):
Zoetermeer
Hekendorp
Harmelen
Hoek van Holland
Hoek van Holland
And a few examples from 1600 - 1700:
Utrecht
Zwolle
Sources:

Monday, May 21, 2012

Sonification - sound of sand - 9

Spectral components - In the samples below you can listen to the spectral components of the following shapes:
01 circle - mp3 - the circle has (almost) no harmonics
02 triangle - mp3 - the triangle has odd and even harmonics - like the sawtooth
03 square - mp3 - the square has only odd harmonics - like the square wave
04 star - mp3 - star has more harmonics than square
05 horizontal rectangle - mp3 - rectangle has very similar harmonics as the square
06 random shape - mp3 - random shape has the most harmonics

Each sample consists of two parts: (1) the separate spectral components, (2) the spectral components added together. Surprisingly enough these sounds are almost musical.

We could start sonifying sand grains right away but I want to explore more possibilities first.

Thursday, May 17, 2012

Sonification - sound of sand - 8

Amplitude and spectrum combined - Now we have programmed the resampling correctly and the shape X- and Y-components are now present in both the spectrum and (on a micro level) in the amplitude of the signal. This is conceptually very satisfying and the sound has become much more interesting:

I'll start sonifying real sand grains only after I've explored all the theoretical possibilities. Have patience with me, I still have these possibilities to explore: (1) spectral components, (2) curvature and (3) mapping into "real" space using time differences between the ears of the listener and his distance from the sound source. And (4) I could use the filters of Nsound and try to map 2-D shapes into filtered white noise. Next time I'll do: (1) spectral components.

But I have sonified a few more of my test shapes:


Warning and disclaimer - These sounds could harm your sound system and could startle your pets. Turn the volume down before playing them.

I will stop exploring the X- and Y-shape components for the moment. Next time I'll try to sonify the 2-D spectral components of the shape. Just a few pictures:
 The spectrum of the star shape signal: X = top, Y = bottom.
The waveform of the star shape signal: X = top, Y = bottom.



from Nsound import *
import math


debug1 = False
debug2 = False
debug3 = True


def convert_chaincode_to_x(c,x):
    if c == 1 or c == 0 or c == 7: x = x + 1; return (x)
    elif ( c == 2 or c == 6): x = x; return (x)
    else: x = x - 1; return (x)


def convert_chaincode_to_y(c,y):
    if c == 1 or c == 2 or c == 3: y = y + 1; return(y)
    elif c == 4 or c == 0: y = y; return(y)
    else: y = y - 1; return(y)


# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_xy_buffers(filename):
    infile = open(filename)
    instr = infile.read()
    infile.close()
    if debug1: print instr
    # parse the input file - split it into words
    inwords = instr.split(' ')
    if debug1: print inwords
    # delete anything except the chain code
    i = 0
    for str in inwords:
        if str.find('0E+0') > -1 :
            break
        i = i + 1
    inwords = inwords[i+2:len(inwords)-1]
    if debug1: print inwords
    # fill the x and y buffers with the chaincode values
    b_x_chaincode = Buffer()
    b_y_chaincode = Buffer()
    x = 0; y = 0
    for str in inwords:
        c = int(str)
        x = convert_chaincode_to_x(c,x)
        b_x_chaincode << x
        y = convert_chaincode_to_y(c,y)
        b_y_chaincode << y
    b_x_chaincode = b_x_chaincode - b_x_chaincode.getMean()
    b_y_chaincode = b_y_chaincode - b_y_chaincode.getMean()
    if debug2:
        b_x_chaincode.plot("x value from chaincode")
        Plotter.show()
        b_y_chaincode.plot("y value from chaincode")
        Plotter.show()
    return(b_x_chaincode, b_y_chaincode)


def convert_xy_frequency(xy, minxy, maxxy, minf, maxf):
    r = float(maxf - minf)/float(maxxy - minxy)
    f = (xy - minxy)*r + minf
    return (f)


def resample_list_frequency_duration(shape_list, list_freq, samp_freq, duration):
    res_buf = Buffer()
    real_duration = int(math.ceil(duration * list_freq)) / list_freq
    res_len = int(math.ceil(real_duration * samp_freq))
    t_samp_freq = 1.0 / samp_freq
    t_list_freq = 1.0 / (list_freq * len(shape_list))
    for i in range(res_len):
        res_buf << shape_list[int(round(i * t_samp_freq / t_list_freq))%len(shape_list)]
    return(res_buf)


# ==============================

# read file into buffers
b_x_chaincode, b_y_chaincode = read_chc_file_to_xy_buffers("C:\\Users\\user\\Documents\\shape\\shape\\04 star.chc")


# copy buffer to list so we can point to it by index
list_x = b_x_chaincode.toList()
list_y = b_y_chaincode.toList()


# generate a frequency modulated x and y signal
b_x_long = Buffer()
b_y_long = Buffer()

min_f = 40.0
max_f = 2000.0
sampling_rate = 44100.0
sound_pixel_duration = 0.01

min_x = b_x_chaincode.getMin()
max_x = b_x_chaincode.getMax()


if debug3: i=0

for x in b_x_chaincode:
    frequency = convert_xy_frequency(x, min_x, max_x, min_f, max_f)
    b_x_long << resample_list_frequency_duration(list_x, frequency, sampling_rate, sound_pixel_duration)


    if debug3:
        i = i+1
        p = int(len(b_x_chaincode)/5)
        if i%p == 0:
            b = Buffer()
            b = resample_list_frequency_duration(list_x, frequency, sampling_rate, sound_pixel_duration)
            b.plot(frequency)
            Plotter.show()


b_x_long.normalize()

min_y = b_y_chaincode.getMin()
max_y = b_y_chaincode.getMax()
for y in b_y_chaincode:
    frequency = convert_xy_frequency(y, min_y, max_y, min_f, max_f)
    b_y_long << resample_list_frequency_duration(list_y, frequency, sampling_rate, sound_pixel_duration)

b_y_long.normalize()

# code the x and y signal into the left and right channel of an audio stream
# write the audio stream into a .wav file
a = AudioStream(sampling_rate, 2)
a[0] = b_x_long
a[1] = b_y_long
a.writeWavefile("C:\\Users\\user\\Documents\\shape\\shape\\04 star xy_freq_shape2.wav")