## Playing StarCraft on Ubuntu 14.04 and X230

I recently got a used X230 tablet and tried to have some fun on it. StarCraft runs well with wine but cannot run on full screen. One possible solution is to open another X server following this post. But I need some tweaks for 14.04 and for touch and stylus to work.

Section "ServerLayout"
Identifier     "SCLayout"
Screen      0  "StarCraft Screen"
InputDevice    "Keyboard0" "CoreKeyboard"
InputDevice    "Mouse0" "CorePointer"
EndSection

Section "Screen"
Identifier     "StarCraft Screen"
Device         "Device0"
Monitor        "StarCraft Monitor"
DefaultDepth    24
SubSection     "Display"
Virtual     640 480
Depth       24
Modes      "640x480@60" "1280x800@50"
EndSubSection
EndSection

Section "Monitor"
Identifier     "StarCraft Monitor"
VendorName     "Plug 'n' Play"
ModelName      "Plug 'n' Play"
Gamma           1
ModeLine       "640x480@60" 25.2 640 656 752 800 480 490 492 525  -hsync -vsync
EndSection

to /etc/X11/xorg.conf. However, xorg.conf is no longer there by default. One can generate one following this.

One would also need to modify the line

allowed_users=console

in /etc/X11/Xwrapper.config to

allowed_users=anybody

For audio to work, one need to add current user to the audio group. Run

sudo usermod -a -G audio $USER Some posts mentioned that one needs to reboot. But I am not certain it is a must. Finally, create the following script and run it. #!/bin/sh X :1 -layout SCLayout -ac & XPID=$!
sleep 2
xbindkeys --display :1 -f $HOME/.scbind #pax11publish -D :1 -e DISPLAY=:1 xsetwacom --set 10 area "3454 -41 24103 15420" DISPLAY=:1 xsetwacom --set 11 area "348 0 2432 1569" DISPLAY=:1 xsetwacom --set 15 area "3454 -41 24103 15420" DISPLAY=:1 xsetwacom --set 10 TabletPCButton "off" DISPLAY=:1 wine$HOME/tmp/StarCraft/StarCraft.exe -- /usr/bin/X :1 -layout SCLayout
sleep 1
kill $XPID I assume StarCraft folder is under$HOME/tmp. Modify it accordingly.

The xsetwacom lines attempt to “calibrate” the touch screen and stylus accordingly. These numbers should work well for X230. For other tablet, You may obtain this number by first changing the resolution to 800×600. Then run “Wacom Tablet”->”Calibrate…” and extract the number by typing

xsetwacom --get 10 area

Note that device “11” is the “finger touch” and ubuntu’s calibration function will only work for the stylus. But one can get the number easily by scaling the number obtained above. For example, dividing each number for devices 10 and 15 by 10 probably will work well for 11 (finger touch). But I didn’t try any other tablet pc other than X230.

## Goagent experience

I am in Shanghai a couple days and it is quite inconvenient with many websites blocked. I heard about “breaking” the wall but I didn’t realize it is quite fast and easy. All one needs is a software called goagent. It takes advantage of the google app engine. Here, I will assume that ones already have created a google app engine application before. If not, it is easy to do and there are many guides for that.

I am using it on my linux box LTS 12.04. The goagent team has created a very good guide on its site. I have encountered few problems following it. It appears that one can’t install gevent automatically for 12.04 and have to use the manual route. And I didn’t try to start the proxy automatically. I just run it in a terminal using

python proxy.py

instead. In any case, I will only be here for a couple days. I don’t really see any inconvenience running it from terminal rather than having it to start up automatically.

In terms of browser setup, I use chromium (chrome should work too) and SwitchySharp. One would want to look for an option file SwitchyOptions.bak and import it directly to SwitchySharp. It can be easily found with a search.

The only issue I had is that it didn’t load facebook and youtube correctly. It appeared that it was due to some certification problems. But it can be fixed easily following this post.

## M/M/1 Simulation with Matlab

A simple simulation of M/M/1 queue with Matlab. The distribution of the number of “packets” in the system is computed and compared with the theoretical result.

delta=0.1; % simulation step in sec
lambda=0.1; % arrival rate in packets per second
mu=0.2; % departure rate in packets per second
rho=lambda/mu;
M=50*3600/delta; % number of simulation step for 50 hours
a=zeros(M,1); % arrival log
d=zeros(M,1); % departure log
n=zeros(M,1); % number of packets at each simulation time step
n_cur=0; % current number of packets in the system
for i=1:M
n_cur; % # packets before the process
n(i)=n_cur; % record the # of packet before the process
if rand < lambda*delta % probability of an arrival occurred = lambda * delta
a(i)=1;
n_cur=n_cur+1;
end
if rand < mu*delta && n_cur > 0 % probability of departure occurred = mu * delta provided that there is a packet in the system
d(i)=1;
n_cur=n_cur-1;
end
if mod(i,1000)==0 % show progress for every 1000 simulation steps
i
end
end
figure;
edges=0:10;
count=histc(n,edges);
bar(0:length(count)-1,count/sum(count));
hold;
nlist=0:length(count)-1;
plot(nlist, (1-rho)*rho.^(nlist),'r-+');
legend('experiment','theory');
title('Distribution of number of packets in the system');



Now, let say if we want to find the delay distribution for the packet arrived when there are 2 packets in the system.

figure;
ainds=find(a==1); % the indices when we have an arrival
atimes=ainds*delta; % arrival times in seconds
dtimes=find(d==1)*delta; % departure times in second
delays=dtimes-atimes(1:length(dtimes)); % list of delays in second
inds=find(n(ainds)==2); % find indices of packets arrived when # packets in system is 2
h=histc(delays(inds),0:60);
bar(0:60,h/sum(h));
hold;
ezplot(mu^3/2*t^2*exp(-mu*t),[0,60]);
legend('experiment','theory');
title('Delay distribution for packets arrived when # packets in system is 2');
xlabel('Time in second');
ylabel('Probability');



## Simulating Poisson process in Matlab

Below is a simple Matlab code to simulate a Poisson process. The interarrival times were computed and recorded in int_times. The times are then grouped into bins of 10 seconds in width and the counts are stored in count.

lambda=1/60; % arrival rate per second (1 minute per packet)
T=10*3600; % simulation time in second (10 hours)
delta=0.1; % simulation step size in second
N=T/delta; % number of simulation steps
event=zeros(N,1); % array recording at each step if a "packet" arrived.
% initialize it to zeros
R=rand(size(event)); % generate a random array (with elements in [0,1]) of the same size as "event"
event(R<lambda*delta)=1; % set each element of event to 1 with probability lambda*delta
inds=find(event==1); % getting indices of arrivial
int_times=diff(inds)*delta; % interarrival times in seconds
edges=0:10:400; % define histogram bin
count=histc(int_times,edges);

The histogram of the absolute counts of the interarrivial is then plotted with the commands below.

figure; bar(edges,count,'histc'); % draw histogram of absolute count



Finally, the counts are normalized and compared with the theoretical result ($\lambda \exp(-\lambda T)$).

figure; bar(edges,count/sum(count)/(edges(2)-edges(1)),'histc'); % draw histogram of normalized counts
hold;plot(edges,lambda*exp(-lambda*edges),'r'); % plot theoretical result
legend('simulation','theoretical');



## ibus jyutping

As a cantonese from HK, I didn’t know how to “type from my mouth” as a kid. I learned Cangjie during high school but I have never become really proficient with it. Chinese is not exactly a phonetic language. But when I write IM, email, or just blog in Chinese. I found it much better to type phonetically as I don’t need to switch my thought to letter ideograph. When I write to mandarin friends, pinyin is great. However, when I chat to friends back home in HK, my message will have “accent” when I try to type in pinyin since I try to “speak” my thought in mandarin when I type.

I finally ended up to have the will to learn jyutping last year. One of the romanization system for Cantonese. I won’t say it is a perfect system (I know it is a standard for linguist but I still found it quite weird to use j for y). Both android and windows have decent input method for jyutping. As for Ubuntu…, there is a jyutping for ibus. But saying it to be horrible is actually a compliment. It is essentially unusable as many common words are missing. And the table is sorted in an absolutely ridiculous way with the top of the table starting with words that no native speakers will ever use.

Fortunately, ibus-table does come with a function to allow users create their own tables. After getting character frequency from Chih-Hao Tsai’s site and jyutping phonetic from HanConv, at least I can build a usable table for myself. There is still lots of tweakings to do though as HanConv does not cover the sounds for all the characters from Chih-Hao Tsai. And some of the pronunciations seem incorrect or at least uncommon. I guess I will make another post to share the final table when it becomes more mature.

## Notes on Bloom Filter

Here are some notes after listening to a coursera lecture of Algorithm 1 by Professor Roughgarden at Stanford.

The goal of a Bloom filter is to provide a space efficient hash for some data entries. The insertion and validation of an entry are very efficient. But a trade-off is that deletion is not possible and it is possible to have a small but finite rate of false positive during validation.

The main idea of a Bloom filter is very simple. Its core is composed of a number (let say $k$) of hash functions and an array of $n$ binary numbers $A$. The hash functions will map any data entry to a number from $1$ to $n$. Given an entry $d$, a bloom filter simply set the $h_i(d)$, $i=1,\cdots,k$, bits of $A$ as one during insertion, where $h_i(d)$ is the hash output of $i$th hash function. During validation, a bloom filter will decide an input entry $e$ has been inserted before if $h_i(e)=1$ for $i=1,\cdots,k$.

One can easily see that it is impossible to have false negative but it can have false positive. Given an input $e$ during validation, without loss of generality, let say the $h_i(e)=i$ for $i=1,\cdots,k$. Let say if we have already $|S|$ entries inserted to the bloom filter, then $Pr(A(1)=1)=1-Pr(A(1)=0)=1-((n-1)/n)^{k|S|}$$\approx 1-e^{k|S|/n}$ for large $n$. Let us denote $b\triangleq n/|S|$ as the number of bit used per entry. Then, $Pr(A(1)=1)=1-e^{k/b}$ and the false positive rate is simply $Pr(A(1)=1\quad \&\quad A(2)=1 \quad\&\cdots \&\quad A(k)=1)=(1-e^{k/b})^k$.