Wednesday, November 7, 2007

Core Erlang + "GS" = GUI version of the "Insertion Sort"

In this article, i got another popular sorting algorithm commonly known as the "Insertion Sort". Basically, this sort an example of (a) in-place , (b) comparison-sort .You may wish to consult your favourite algorithm texts or visit the Wikipedia (I've heard its rather unreliable but i'm not so sure why). Again like all my previous articles, there are two parts to this: (a) Non-graphical, (b) Graphical version.

Here's the codes:

Filename: "isort.erl"
-module(isort).
-export([start/1]).
-copyright('Copyright (c) 2007 Raymond Tay').
-vsn('$Revision: 1').
%
%
% The insertion sort is a good middle-of-the-road choice for sorting lists of
% a few thousand items or less. The algorithm is significantly simpler than
% the shell sort, with only a small trade off in efficiency. At the same time
% the insertion sort is over twice as fast as the bubble sort and almost 40%
% faster than the selection sort. The insertion sort shouldn't be used for
% sorting lists larger than a couple thousands items or repetitive sorting
%of lists larger than a couple hundred items
%
% insertionSort(array A)
% for i = 1 to length[A]-1 do
% value = A[i]
% j = i-1
% while j >= 0 and A[j] > value do
% A[j + 1] = A[j]
% j = j-1
% A[j+1] = value
%

genNum(N,N,L,F,Num) -> [F(Num),L];
genNum(I,N,L,F,Num) -> Val = F(Num), genNum(I+1,N,[Val,L],F,Num).

for(N,N,F,L) -> Val = lists:nth(N,L), J = N - 1,T = lists:nth(J,L), F(J,L,Val,T);
for(I,N,F,L) -> Val = lists:nth(I,L), J = I - 1,T = lists:nth(J,L), L2 = F(J,L,Val,T), for(I+1,N,F,L2).

checkNInsert(Index,L,Value,T) when Index >= 1 andalso T > Value ->
{L1,L2} = lists:split(Index,L),
[_H|T1] = L2,
Temp1 = lists:flatten(lists:append([L1],[T])),
Temp2 = lists:append(Temp1, T1),
if
Index - 1 /= 0 ->
NewVal = lists:nth(Index - 1, Temp2),
checkNInsert(Index - 1, Temp2, Value, NewVal);
Index - 1 =:= 0 ->
checkNInsert(Index - 1, Temp2, Value, Value)
end;
checkNInsert(Index,L,Value,T) when Index =< 1 orelse T =< Value ->
{L1,L2} = lists:split(Index,L),
[_H|T1] = L2,
lists:append(lists:append(L1,[Value]),T1).

start(N) ->
L = lists:flatten(genNum(1,N,[],fun random:uniform/1, N)),
for(2, length(L), fun checkNInsert/4, L).

And next is for the graphical version

Filename: "isortgui.erl"
-module(isortgui).
-export([start/0]).
-copyright('Copyright (c) 2007 Raymond Tay').
-vsn('$Revision: 1').
%
% The insertion sort is a good middle-of-the-road choice for sorting lists of
% a few thousand items or less. The algorithm is significantly simpler than
% the shell sort, with only a small trade off in efficiency. At the same time
% the insertion sort is over twice as fast as the bubble sort and almost 40%
% faster than the selection sort. The insertion sort shouldn't be used for
% sorting lists larger than a couple thousands items or repetitive sorting
% of lists larger than a couple hundred items
%
% insertionSort(array A)
% for i = 1 to length[A]-1 do
% value = A[i]
% j = i-1
% while j >= 0 and A[j] > value do
% A[j + 1] = A[j]
% j = j-1
% A[j+1] = value
%
forL(N,N,{stretch,_N,_X}) -> [{stretch,_N,_X}];
forL(I,N,{stretch,_N,_X}) -> [{stretch,_N,_X}|forL(I+1,N,{stretch,_N,_X})].

for(N,N,F,L) -> {_,Val} = gs:read(dict:fetch({1,N},L),label), J = N - 1, {_,T} = gs:read(dict:fetch({1,J},L),label), {Val1,_} = string:to_integer(Val), {T1,_} = string:to_integer(T),F(J,L,Val1,T1);
for(I,N,F,L) -> {_,Val} = gs:read(dict:fetch({1,I},L),label), J = I - 1, {_,T} = gs:read(dict:fetch({1,J},L),label), {Val1,_} = string:to_integer(Val), {T1,_} = string:to_integer(T), D2 = F(J,L,Val1,T1), for(I+1,N,F,D2).

checkNInsert(Index,L,Value,T) when Index >= 1 andalso T > Value ->
ButId = dict:fetch({1,Index+1},L),
gs:config(ButId, [{label, {text, T}}]),
gs:config(ButId, [flash]),
sleep(50),
if
Index - 1 =:= 0 -> checkNInsert(0,L,Value,Value);
Index - 1 /= 0 ->
{_,Val} = gs:read(dict:fetch({1,Index -1},L),label),
{Val1,_} = string:to_integer(Val),
if
Val1 =< Value -> checkNInsert(Index - 1, L, Value, Value);
Val1 > Value -> checkNInsert(Index - 1, L, Value, Val1)
end
end;
checkNInsert(Index,L,Value,T) when Index =:= 0 orelse T =< Value ->
ButId = dict:fetch({1,Index+1},L),
gs:config(ButId, [{label, {text, Value}}]),
gs:config(ButId, [flash]),
L.

isort(Dict) ->
for(2, 50, fun checkNInsert/4, Dict). % Sort it for 2-to-<number of columns in GUI>

start() ->
D = dict:new(),
WH = [{width, 1000}, {height, 50}],
Win = gs:window(gs:start(), [{map, true}, {configure, true}, {title, "Insertion-Sort Algorithm"} |WH]),
XOpts = forL(1,50,{stretch,1,20}),
YOpts = [{stretch,1,20}],
gs:frame(packer, Win, [{packer_x, XOpts}, {packer_y, YOpts}]),
NewD = genBut(1,1,D),
gs:config(packer,WH),
dumpDict(NewD),
isort(NewD),
dumpDict(NewD),
io:format("algo done~n",[]),
loop().
%
%
% Generate the "button" GUI objects
%
genBut(Row,Col,Dict) when Col =< 50 ->
ButId = gs:button(packer, [{label, {text, random:uniform(50)}}, {pack_xy, {Col,Row}}]),
NewDict = dict:store({Row,Col}, ButId, Dict), % used later for GUI manipulation
genBut(Row,Col+1,NewDict);
genBut(Row,Col,Dict) when Col > 50 -> Dict.

%
% Pretty standard GUI-event loop
%
loop() ->
receive
{gs,_Id,destroy,_Data,_Arg} -> bye;
{gs,_Id,configure,_Data,[W,H|_]} ->
gs:config(packer, [{width,W}, {height,H}]), %refresh to initial size
loop();
_Other -> loop()
end.
%
% Pretty standard "sleep" function
%
sleep(T) ->
receive
after T -> ok
end.

%
% Dump the dictionary
%
dumpDict(D) ->
Keys = lists:sort(dict:fetch_keys(D)),
lists:foreach( fun({R,C}) -> Val = gs:read(dict:fetch({R,C},D),label), io:format("{~p,~p}->~p~n", [R,C,Val]) end, Keys).
While the algorithm is executing, you will notice that the buttons will flash every time it detects a re-positioning is required. Here is a screen shot and do let me know if you have any comments, it would be much appreciated; that applies to ideas as well :-)


Saturday, November 3, 2007

Core Erlang + "GS" = GUI version of the "BubbleSort"

Everyone who has studied Computer Science would know about the Bubble Sort algorithm. This is a simple sorting algorithm which runs at O(n^2). You may wish to consult your standard data structure text or the above hyperlink for further information.

Since this particular blog of mine is about Erlang and also i'm quite "hooked" to it, so again this article is about illustrating this algorithm implemented using Erlang. It's a fun exercise.

I have included source codes for running 2 versions: (a) Non-graphical and (b) Graphical.

%
% This is an attempt to create a GUI version of the "Bubble Sort"
%
% procedure bubblesort(A:list of unsorted items) defined as:
% do
% swapped := false
% for each i in 0 to length(A) -2 do
% if A[i] > A[i+1] then
% swap(A[i], A[i+1])
% swapped := true
% end if
% end for
% while swapped
% end procedure

-module(bsort).
-export([start/1, init/1]).
-copyright('Copyright (c) 2007 Raymond Tay').
-vsn('$Revision: 1').

start(N) -> spawn(bsort, init, [N]).

%
% Standard "for"-loop concept
%
for(N,N,Dict,F,Num) -> Val = F(Num), NewDict = dict:store(N,Val,Dict), NewDict;
for(I,N,Dict,F,Num) -> Val = F(Num), NewDict = dict:store(I,Val,Dict), for(I+1,N,NewDict,F,Num).

% Swaps the value but not the position of the record
%
swap({Pos1,Value1},{Pos2,Value2},Dict) ->
NewDict1 = dict:store(Pos1,Value2,Dict),
NewDict2 = dict:store(Pos2,Value1,NewDict1),
NewDict2.

%
% BubbleSort implementation
%
bsort(D,Swapped) when Swapped =:= false -> D;
bsort(D,Swapped) when Swapped =:= true ->
Len = erlang:length(dict:fetch_keys(D)),
{Again, NewDict} = checkNSwap(D,1,Len, false),
bsort(NewDict,Again).

%
% Check-N-Swap
%
checkNSwap(Dict,N,N,Again) -> {Again,Dict};
checkNSwap(Dict,I,N,Again) ->
Ele1 = dict:fetch(I,Dict),
Ele2 = dict:fetch(I+1,Dict),
if
Ele1 > Ele2 -> NewDict = swap({I,Ele1},{I+1,Ele2},Dict), checkNSwap(NewDict, I+1,N,true);
Ele1 =< Ele2 -> checkNSwap(Dict,I+1,N,Again)
end.

init(N) -> Dict = dict:new(),
NewDict = for(1,N,Dict, fun random:uniform/1, N),
dumpDict(bsort(NewDict,true)).


dumpDict(Dict) ->
Keys = lists:sort(dict:fetch_keys(Dict)),
lists:foreach(fun(X) -> io:format("{~p,~p} ...", [X,dict:fetch(X,Dict)]) end, Keys).

The next is the source code for the graphical version of the "Bubble Sort" and some screen-shots of the algorithm in action. I used an 25 x 25 "grid" composed of buttons (Will explore using the canvas when i have more time) and i tried the 100 x 100 "grid" but it didn't work out on my laptop as i had some resolution problems, but i think as an exercise a 25 x 25 was good enough for me :-)

-module(bsortgui).
-export([start/0]).
%
% BubbleSort implementation
%
bsort(D,Swapped) when Swapped =:= false -> D;
bsort(D,Swapped) when Swapped =:= true ->
{Again, NewDict} = checkNSwap(D,1,25, false),
bsort(NewDict,Again).

%
% Swaps the value but not the position of the record
%
swap({Pos1,Value1,ButId1},{Pos2,Value2,ButId2},Dict) ->
gs:config(ButId1,[{label, {text, ""}}]),
gs:config(ButId2,[{label, {text, ""}}]),
NewButId1 = dict:fetch({Value1,Pos2},Dict),
NewButId2 = dict:fetch({Value2,Pos1},Dict),
gs:config(NewButId1,[{label, {text, Value1}}]),
gs:config(NewButId2,[{label, {text, Value2}}]),
NewDict1 = dict:store(Pos1,{Value2,NewButId2},Dict),
NewDict2 = dict:store(Pos2,{Value1,NewButId1},NewDict1), NewDict2.

sleep(T) ->
receive
after T -> ok end.
%
% Check-N-Swap
%
checkNSwap(Dict,N,N,Again) -> {Again,Dict};
checkNSwap(Dict,I,N,Again) ->
{Ele1,ButId1} = dict:fetch(I,Dict),
{Ele2,ButId2} = dict:fetch(I+1,Dict),
%io:format("Col:~p,Row:~p~n", [I,Ele1]),
%io:format("Col:~p,Row:~p~n", [I+1,Ele2]),
if
Ele1 > Ele2 -> NewDict = swap({I,Ele1,ButId1},{I+1,Ele2,ButId2},Dict), sleep(300), checkNSwap(NewDict, I+1,N,true);
Ele1 =< Ele2 -> checkNSwap(Dict,I+1,N,Again)
end.


forL(N,N,{stretch,_N,_X}) -> [{stretch,_N,_X}];
forL(I,N,{stretch,_N,_X}) -> [{stretch,_N,_X}|forL(I+1,N,{stretch,_N,_X})].

%for(N,N,[H|_], D, F) -> F(H,D);
%for(I,N,[H|T], D, F) -> NewD = F(H,D), for(I+1,N,T,NewD,F).

genBut(Row,Col,Dict) when Row*Col =< 625 ->
if
Col =< 25 ->
ButId = gs:button(packer, [{label, {text, ""}}, {pack_xy, {Col,Row}}]),
NewDict = dict:store({Row,Col}, ButId, Dict), % used later for GUI manipulation
%io:format("genBut(), Row:~p, Col:~p, Id:~p~n", [Row,Col,ButId]),
genBut(Row,Col+1,NewDict);
Col > 25 -> genBut(Row+1, 1, Dict)
end;
genBut(Row,Col,Dict) when Row*Col > 625 -> Dict.

%
% Fill each column with exactly 1 random number
%
fillRand(Col,Dict) when Col =< 25 ->
Ran = random:uniform(25),
if
Col =< 25 ->
ButId = dict:fetch({Ran,Col},Dict),
gs:config(ButId, [{label, {text, Ran}}]),
NewDict = dict:store(Col, {Ran,ButId}, Dict), % used later for GUI manipulation
%io:format("Row:~p,Col:~p,Val:~p~n", [Ran,Col,Ran]),
fillRand(Col+1,NewDict)
end;
fillRand(Col,Dict) when Col > 25 -> Dict.



start() ->
D = dict:new(),
WH = [{width, 800}, {height, 800}],
Win = gs:window(gs:start(), [{map, true}, {configure, true}, {title, "BubbleSort Algorithm"} |WH]),
XOpts = forL(1,25,{stretch,1,15}),
YOpts = forL(1,25,{stretch,1,15}),
gs:frame(packer, Win, [{packer_x, XOpts}, {packer_y, YOpts}]),
NewD = genBut(1,1,D),
NewD2 = fillRand(1,NewD),
gs:config(packer,WH),
bsort(NewD2,true),
io:format("Done~n",[]),
loop().
%
% A typical loop for receiving messages
%
loop() ->
receive
{gs,_Id,destroy,_Data,_Arg} -> bye;
{gs,_Id,configure,_Data,[W,H|_]} ->
gs:config(packer, [{width,W},{height,H}]), %refresh to initial size
loop();
_Other -> loop()
end.

Below are some screenshots.



Let me know your comments if you got any :-)

Monday, October 29, 2007

Core Erlang + "GS" = GUI version of the "Sieve"

In this article, i want to demonstrate a bit more about the G.S. Previously, i wrote an extremely simple Erlang Window just to see how it easy it was, apparently it's not very difficult.

What i subsequently did was to combine the both the "GS" and the Sieve of Eratosthenes to produce a graphical version of the "sieving" problem. The point of this exercise was to illustrate how easy it was to code in Erlang once you have gotten used to its semantics, i had fun doing it.

Owing to my laptop's screen resolution, i could only manage a 25-by-25 grid but that's not the point of this exercise. Here are some screen shots and a working code (Code needs to be smoothen though, let me know your comments)

%
% This is an attempt to create a GUI version of the "Sieve of Erasothenes'
%
%
-module(sievegui).
-export([start/0, init/1]).
-copyright('Copyright (c) 2007 Raymond Tay').
-vsn('$Revision: 1').
%
% The following generates a list of multiples-of-Base
% e.g. To generate multiples of 3 less than 100, enter "sieve:genmulti(0,3,100)"
% and you get [9,12,15,18|...]
%
genmulti(Index,Base,Limit) when (Base*Base+Index*Base) > Limit -> [];
genmulti(Index,Base,Limit) when (Base*Base+Index*Base) =< Limit -> [Base*Base+Index*Base | genmulti(Index+1,Base,Limit) ].

sleep(T) ->
receive
after T -> ok
end.
%
% Obtains the GS's "object id" and manipulates the display
%
filterDisplay(ObjId,List) ->
{_,ObjValue} = gs:read(ObjId, label),
{IntValue,X} = string:to_integer(ObjValue),
Result = lists:member(IntValue,List),
if
Result =:= true -> gs:config(ObjId,[{label, {text, ""}}]);
Result =:= false -> ok
end,
sleep(50).
% filterDisplay(ObjId,List) ->
% {_,ObjValue} = gs:read(ObjId, label),
% Result = lists:member(ObjValue,List),
% if
% Result =:= true -> gs:config(ObjId,[{label, {text, ""}}])
% end.

removeMultiples(Index, List, Limit, Dict) when Index /= erlang:length(List) ->
Head = lists:nth(Index,List),
RemoveList = genmulti(0,Head,Limit),
Keys = dict:fetch_keys(Dict),
lists:foreach( fun(X) -> filterDisplay(X,RemoveList) end, Keys),
NewList = List -- RemoveList,
removeMultiples(Index+1, NewList, Limit, Dict);
removeMultiples(Index, List, _, _) when Index =:= erlang:length(List) -> List.


%
% A standard Erlang "for"-loop
%
for(N,N,F) -> F();
for(I,N,F) -> F(),for(I+1,N,F).

forL(N,N,{stretch,_N,_X}) -> [{stretch,_N,_X}];
forL(I,N,{stretch,_N,_X}) -> [{stretch,_N,_X}|forL(I+1,N,{stretch,_N,_X})].
%
% start() -> You can call this if you wish; the only difference between this and init() is that start() starts
% a spawned process
%
start() -> spawn(gsdemo, init, [625]).

%
% Generates the GUI for the button
% where the label for each button is that of incremental number
%
genBut(Row,Col,Text,Dict) when Row*Col =< 625 ->
if
Col =< 25 ->
%io:format("R:~p,C:~p,T:~p~n", [Row,Col,erlang:integer_to_list(Text,10)]),
ButId = gs:button(packer, [{label, {text, erlang:integer_to_list(Text,10)}}, {pack_xy, {Col,Row}}]),
NewDict = dict:store(ButId, ButId, Dict),
NewText = Text+1,
genBut(Row,Col+1, NewText, NewDict);
Col > 25 -> genBut(Row+1, 1, Text, Dict)
end;
genBut(Row,Col,_Text, Dict) when Row*Col > 625 -> Dict.

%
% init() - You can call this if you wish
%
init(Num) ->
_Dict = dict:new(), % process dictionary
WH = [{width, 800}, {height, 800}],
Win = gs:window(gs:start(), [{map, true}, {configure, true}, {title, "Sieve of Erasothenes"} |WH]),
XOpts = forL(1,25,{stretch,1,8}),
YOpts = forL(1,25,{stretch,1,8}),
gs:frame(packer, Win, [{packer_x, XOpts}, {packer_y, YOpts}]),
NewDict = genBut(1,1,2,_Dict),
gs:config(packer, WH), %refresh to initial size
List = lists:seq(2,Num),
FinalList = removeMultiples(1, List, lists:max(List), NewDict),
loop().
%
% A typical loop for receiving messages
%
loop() ->
receive
{gs,_Id,destroy,_Data,_Arg} -> bye;
Other -> loop()
end.
There are three screenshots below of this application to illustrate the program sieving through the numbers

That's it, all comments are welcome.

Sunday, October 14, 2007

Erlang Hot Code Swapping

In this post, i'm going to repeat Joe Armstrong's technique of hot code swapping using Erlang. It's a extremely powerful technique which basically allows you to swap/interchange code without restarting the server(s).Joe Armstrong, in his book, demonstrated the technique of hot swapping and i would like to repeat that with a J2EE twist to it. To my knowledge, most J2EE container cannot perform this smoothly yet; however, do let me know if my information is not correct.

What i have is a simple Stateless Session EJB (Enterprise Java Bean). The J2EE container model uses a callback invocation + client-server architecture so that the container can run both client and lifecycle functions.

Filename: "Converter.java" --- Actual EJB remote class
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
import java.math.*;

public interface Converter extends EJBObject {
public BigDecimal dollarToYen(BigDecimal dollars) throws RemoteException;
public BigDecimal yenToEuro(BigDecimal yen) throws RemoteException;
}

Filename: "ConverterHome.java" --- Actual EJB Home class
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface ConverterHome extends EJBHome {
Converter create() throws RemoteException, CreateException;
}

Filename: "ConverterBean.java" --- Actual EJB class

import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import java.math.*;

public class ConverterBean implements SessionBean {

BigDecimal yenRate = new BigDecimal("121.6000");
BigDecimal euroRate = new BigDecimal("0.0077");

public BigDecimal dollarToYen(BigDecimal dollars) {
BigDecimal result = dollars.multiply(yenRate);
return result.setScale(2,BigDecimal.ROUND_UP);
}

public BigDecimal yenToEuro(BigDecimal yen) {
BigDecimal result = yen.multiply(euroRate);
return result.setScale(2,BigDecimal.ROUND_UP);
}

public ConverterBean() {}
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}
So, how do you accomplished the above to the Erlang equivalent? The toughest part is building a framework that will invoke the lifecycle methods like those ejbXXX as well as conformation to the specifications laid out by the J2EE Community and i will skip that part, for now and hence, i will concentrate on the client-server part as well as hot code swapping. Below is my attempt at the above mentioned J2EE implementation.

Filename: "callback.erl"
-module(callback).
-export([init/0, ejbActivate/0, ejbPassivate/0, ejbRemove/0, dollarToYen/1, yenToEuro/1, handle/2]).
-import(container, [rpc/2]).

%% client routines
dollarToYen(Dollars) -> rpc(ejbserver, {convertToYen, Dollars}).
yenToEuro(Yen) -> rpc(ejbserver, {convertToEuro, Yen}).
ejbActivate() -> rpc(ejbserver, {ejbactivate}).
ejbPassivate() -> rpc(ejbserver, {ejbpassivate}).
ejbRemove() -> rpc(ejbserver, {ejbremove}).

%% callback routines
init() -> dict:new().

handle({convertToYen, Dollars}, Dict) -> { Dollars * 126, Dict};
handle({ejbactivate}, Dict) -> { ejbActivate , Dict};
handle({ejbpassivate}, Dict) -> { ejbPassivate , Dict};
handle({ejbremove}, Dict) -> { ejbRemove , Dict};
handle({convertToEuro, Yen}, Dict) -> {Yen * 0.0077, Dict}.

Filename: "container.erl"
-module(container).
-export([start/2, rpc/2, swap_code/2]).

start(Name, Mod) ->
register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)).

swap_code(Name,Mod) -> rpc(Name, {swap_code, Mod}).

%
% Standard code for abstracting the "RPC-call" layer
%
rpc(Name, Request) ->
Name ! {self(), Request},
receive
{Name, Response} -> Response
end.

%
% Standard code for looping and waiting for messages from clients
%
loop(Name, Mod, OldState) ->
receive
{From, {swap_code, NewCallbackMod}} ->
From ! {Name, ack},
loop(Name, NewCallbackMod, OldState);
{From, Request} ->
{Response, NewState} = Mod:handle(Request,OldState),
From ! {Name, Response},
loop(Name, Mod, NewState)
end.

So how do you run it ? Refer to the figure below
I shall briefly explain what i did,
1/ compile the "server"
2/ compile the "callback" a.k.a. EJB
3/ start up the "server"
4/ invoke the callback / EJB to run the interface functions




So, the next thing is how do i do hot code swapping without bringing down the server? What you need to do first is to decide what your replacement code is going to be and swap it with the code that was just running. E.g. let's assume that i have decided to replace the callback.erl with another code callback2.erl and i want to replace the former with the latter.

Filename: "callback2.erl"
-module(callback2).
-export([init/0, ejbActivate/0, ejbPassivate/0, ejbRemove/0, dollarToYenSpecial/1, yenToEuroSpecial/1, handle/2]).
-import(container, [rpc/2]).

%% client routines
dollarToYenSpecial(Dollars) -> rpc(ejbserver, {convertToYen, Dollars}).
yenToEuroSpecial(Yen) -> rpc(ejbserver, {convertToEuro, Yen}).
ejbActivate() -> rpc(ejbserver, {ejbactivate}).
ejbPassivate() -> rpc(ejbserver, {ejbpassivate}).
ejbRemove() -> rpc(ejbserver, {ejbremove}).

%% callback routines
init() -> dict:new().

handle({convertToYen, Dollars}, Dict) -> { Dollars * 126 * 126, Dict};
handle({ejbactivate}, Dict) -> { ejbActivate , Dict};
handle({ejbpassivate}, Dict) -> { ejbPassivate , Dict};
handle({ejbremove}, Dict) -> { ejbRemove , Dict};
handle({convertToEuro, Yen}, Dict) -> {Yen * 0.0077 * 0.0077, Dict}.
The changes are highlighted in bold for easy viewing. After, you need to compile it and swap it with the running code. Note that the Mod:init() does not run again. Refer to the figure below for a sample hot code swapping.









I hope this demonstrates how powerful Erlang can be and possibly a replacement language for Java and the like?

Saturday, October 6, 2007

Sieve of Eratosthenes

People whom studied computer science has heard of the "Sieve of Eratosthenes" and i took the implementation in Erlang as an exercise and collected the run-times of the program to determine the number of primes less than 120, 1000, 10000, 100000 and 1000000.


Filename: "sieve.erl"
-module(sieve).
-export([findPrimes/1, genmulti/3, removeMultiples/3]).

%
% The following generates a list of multiples-of-Base
% e.g. To generate multiples of 3 less than 100, enter "sieve:genmulti(0,3,100)"
% and you get [9,12,15,18|...]
%
genmulti(Index,Base,Limit) when (Base*Base+Index*Base) > Limit -> [];
genmulti(Index,Base,Limit) when (Base*Base+Index*Base) =<> [Base*Base+Index*Base | genmulti(Index+1,Base,Limit) ].

removeMultiples(Index, List, Limit) when Index /= erlang:length(List) ->
Head = lists:nth(Index,List),
NewList = List -- genmulti(0,Head,Limit),
removeMultiples(Index+1, NewList, Limit);
removeMultiples(Index, List, _) when Index =:= erlang:length(List) -> List.

findPrimes(Num) -> List = lists:seq(2,Num),
statistics(runtime),
statistics(wall_clock),
FinalList = removeMultiples(1, List, lists:max(List)),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
io:format("Total discovered primes:~w~n", [erlang:length(FinalList)]),
io:format("Runtime:~w(s) Wall-clock Time:~w(s)~n", [Time1/1000, Time2/1000]),
lists:foreach( fun(X) -> io:format("~w, ", [X]) end, FinalList).

To run this, there are a few ways you can do this in Erlang but the most common is the following:
1/ Copy-paste the code into a file of your choice, in my case its "sieve.erl"
2/ Start a Erlang shell
3/ Compile the program via "c(sieve)."
4/ Execute the program via "sieve:findPrimes(120)" which is to find the number of primes numbers less than or equal to 120.

My program will reveal how many primes have been discovered and the computation time it took and you can counter check the number of primes discovered against this site How Many Primes Are There?

Finally, the run-times for discovering the number of primes less than 120, 1000, 10000, 100000 and 1000000 are displayed below.


sieve:findPrimes(120).
Total discovered primes:30
Runtime:0.00000e+0(s) Wall-clock Time:0.00000e+0(s)

sieve:findPrimes(1000).
Total discovered primes:168
Runtime:1.00000e-2(s) Wall-clock Time:9.00000e-3(s)

sieve:findPrimes(10000).
Total discovered primes:1229
Runtime:0.290000(s) Wall-clock Time:0.295000(s)

sieve:findPrimes(100000).
Total discovered primes:9592
Runtime:29.8900(s) Wall-clock Time:30.0060(s)

sieve:findPrimes(1000000).
Total discovered primes:78498
Runtime:3025.86(s) Wall-clock Time:3042.31(s)

Friday, October 5, 2007

Using the Graphical System a.k.a "gs" module in Erlang

In this article, i want to present some basic usage of the graphical system otherwise known as the Erlang module "gs". The pre-requisites is the requirement for Tcl/Tk to be installed on your Linux system, otherwise you will get the error "{error,backend_died}" when you invoke the "gs:start()" and lastly include the path to your linux user so that Erlang can locate the "tk".

I have a contrived example of a simple Erlang GUI

-module(simple_window).
-export([start/0]).

start() ->
Id = gs:start(),
Win = gs:create(window, Id, [{width, 200}, {height, 100}],
Butt = gs:create(button, Win, [{label, {text, "Press Me"}}, {x, 0}]),
Butt2 = gs:create(button, Win, [{label, {text, "Stop"}}, {x, 100}]),
gs:config(Win, {map, true}),
loop(Butt, Butt2, Win).

loop(Butt, Butt2, Win) ->
receive
{gs, Butt, click, Data, Args} ->
io:format("Hello There~n", []),
loop(Butt);
{gs, Butt2, click, Data, Args} ->
gs:destroy(Win)
end.

What just happened is this
  1. A graphics server was created via the "gs:start()"
  2. A window was created with the defined width and height
  3. A button was created inside the window with a text
  4. A event-loop was created that will receive the GUI-events from the user
That's about the amount of effort u need to create a simple GUI window. The figure shows a screenshot
From the screenshot, if you keep hitting the button "Press Me" then the Erlang shell will display "Hello There" and if you hit the button "Stop" then the window will close cleanly

Saturday, September 29, 2007

Erlang/Java Performance in Concurrency

I've been learning Erlang for 1 week now and i discover its a nice language for programming. This language is definitely different from C, C++ and Java.

In this post, i shall boldly compare the difference in runtimes for Erlang and Java w.r.t. concurrency.

In Erlang, I created a file ring.erl which contains the following code


-module(ring).
-export([start/2, for/3, loop/0]).

-ifndef(debug).
-define(TRACE(X), io:format("~p:~p ~p~n", [?MODULE, ?FILE, X])).
-else.
-define(TRACE(X), void).
-endif.

for(N, N, F) -> F();
for(I, N, F) -> F(),for(I+1, N,F).

%
% Create N processes and send a message M times
% to each process. Therefore, we should generate N * M
% messages.
%

loop() ->
receive
{msg, Pid} -> Pid, loop()
after 5000 ->
done
end.

start(N, M) ->
statistics(runtime),
statistics(wall_clock),
ring:for(1, N, fun() -> Pid = spawn(ring, loop, []), ring:for(1, M, fun() -> Pid ! {msg, Pid} end) end),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
io:format("Runtime:~p, Walltime:~p~n", [Time1, Time2]).


In Java, I used Netbeans 5.5.1 (JDK 1.5.0_12) to develop the following simple multi-threaded Java code:


package simplemultithread;

public class Main {

/** Creates a new instance of Main */
public Main() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
long startTime = System.currentTimeMillis();
if ( args.length != 2 ) {
System.err.println("usage: java Main <Number of threads> <Number of msg to send to each thread>");
System.exit(-1);
}
int numOfThreads = Integer.parseInt(args[0]);
final int numOfMsgsPerThread = Integer.parseInt(args[1]);
Thread threads[] = new Thread[numOfThreads];

for( int i = 0; i < numOfThreads; i++ ) {
threads[i] = new Thread() {
private int msgsToProcess = numOfMsgsPerThread;
public void run() {
for( int i = 0, j = 0; i < msgsToProcess; i++ ) {
// do something simple
j++;
}
}
};
try { threads[i].join();} catch (InterruptedException ie) {}
}
for( int i = 0; i < numOfThreads; i++ ) {
threads[i].start();
}
long endTime = System.currentTimeMillis();
System.out.println("Total time:" + (endTime - startTime)/1000.00 + "seconds");
}

}


And the performance difference is quite remarkable after comparing the runtimes of both programs which perform almost the same thing i.e. start N processes/threads and each process executes its action M-times.

In my tests, i used a Compaq notebook Intel-M 2.4 Ghz with 512 MB RAM running SUSE Linux 9.3 Professional Operating System.

The figure on the left is the runtime, in milliseconds, of the Erlang code above and that on the right is that of the Java code. From the figures, you can see that Erlang runs better than Java in order of approximately 2-3 times!

How does Erlang do it? The best way to understand it is to see this article.


Wednesday, September 26, 2007

Understand your implementation by "tracing" the execution

In my previous post, i used Erlang to implement 2 simple algorithms when run, produced the desired results which i am pleased. But, upon reflection i found that i need to better my understanding of how Erlang executes the function i knew i needed to trace it.

Therefore, how do you add "debug/trace" feature into your own implementations ?

What i did is:

1/ Create a macro named "TRACE"
2/ Compiled the code using the "c"-command with an extra argument
3/ Ran the compiled code to view it, and voila! its done.

Below is an illustration of how i did it:


%
% Create a Erlang macro and include it in your *.erl file
%
-ifdef(debug).
-define(TRACE(X), io:format("TRACE ~p:~p ~p~n", [?MODULE, ?LINE, X])).
-else.
-define(TRACE(X), void).
-endif.
...
...
...
%
% N-th Permutation
% Note: the code in "bold" is an expansion of the newly created macro "TRACE"
%
perms([]) -> [[]];
perms(L) -> ?TRACE(L), [[H|T] || H <- L, T <- perms(L--[H])]. ... ...


Now, once you have done this naturally you would save the file and next you start up the Erlang shell and compile the file as illustrated in the screenshot below, afterwhich you run it!

Friday, September 21, 2007

Implementing Algorithms (Part 1)

I just started learning this language which belongs to a class of languages known as Functional Language.

For starters, I am going to demonstrate some simple stuff.

1/ Calculate Factorial


%
% Algorithm to calculate the Nth Factorial
%
-module(fac).
-export([factorial/1]).

factorial(0) -> 1;
factorial(1) -> 1;
factorial(N) when N > 0 -> N * factorial(N-1).

2/ Calculate N-th Fibonacci Sequence


%
% Algorithm to calculate the sum of Nth Fibonacci Sequence
%
-module(fib).
-export([fibonacci/1]).

fibonacci(0) -> 0;
fibonacci(1) -> 1;
fibonacci(N) when N > 1 -> fibonacci(N-1) + fibonacci(N-2).

In order to run the above scripts, do the following

a) Create a file call fac.erl or fib.erl (Note: name of file must be the same as the string given in the "-module")
b) Copy and paste the respective code into the respective file
c) Start up the Erlang Shell and type the following (Note the period character '.'):
c.1) c(fib).
c.2) c(fac).
If your compilation was successful, you should have the following screen

Wednesday, September 19, 2007

What is Erlang and what is its role going to be ?

I borrowed the following quote from the book Programming Erlang

For years we have relied on processors getting faster and faster. That trend is ending. Instead, we now have multicore processors - 2, 4 or more processors running in parallel. The problem is, unless your program can execute in parallel, it will use only one of these cores at a time.

The Erlang programming language lets you build highly parallel, distributed, fault-tolerant systems - systems that can exploit these new architectures. It has been used commercially for many years to create massive fault tolerant and highly reliable systems.

Erlang programs run seamlessly on multicore computers with no extra code on your part. Erlang combines ideas from the world of functional programming with techniques for building fault-tolerant systems. The result is a powerful language that makes it much easier to build the massively parallel networked applications of the future.
Therefore, in the coming blogs i am going to write stuff about Erlang and programming in it, in general.

For a brief introduction to the language features, follow this article.