Archive for the ‘english’ Category

hierarchical temporal memory

November 26th, 2008

As is often said, we humans (if you are not one of us you can join on the website, membership fees are high but not impossible) are pattern seeking animals. This implies that it is difficult for us to understand a completely "new kind of thing", we tend to seek something else that we can compare it to. Psychology got a minor win when computers emerged, because it finally had a model for the brain. Psychology professors could point to the computer and say "the brain, it's somewhat like that". It behooves psychology that the computer we know has a distinct memory, a processing/reasoning unit, and input channels that receive transmissions of "sensory perception".

The computer as we know it is the so called Von Neumann architecture, every computer we've ever had has been designed in those basic components. This design is simple enough (and, in fact, dumb enough) to handle just about anything at all, it is the general purpose computer (a way of saying that it doesn't have any purpose).

Now a bunch of neuroscientists have figured out that the memory in our computers is too dumb to do certain things well. Our linear memory, where a memory cell has no relationship to the neighboring cells, is abstract and general enough for anyone's pleasure, but it's not the way human memory works. Our memory is hierarchical, that is to say it's made up of levels where the bottom levels remember very simple things, like shapes and sounds in time. As you ascend the hierarchy, the levels above that do not remember "discrete" things, they remember unifications over the simple things. That is the way in which you understand that a leg is both a discrete thing as well as it can be part of a human body, one part in something larger.

Now, if you think about it, this is a crude first model for learning, you are being fed a lot of facts in the hope that you will be able to unify them and see "meaning" to them as a whole. This, unfortunately, is necessary, because we don't know how to transmit the meaning itself, we think the only way is to send the facts and then the mind will infer the meaning by itself. (It's quite an optimistic strategy, isn't it?) Interestingly, there is a trade off at this point. Apparently, you cannot both remember all the discrete facts *and* be able to unify them. So that could explain how some people have a propensity for lots of facts without seeing the bigger picture, while others can't hold on to all the little pieces. In a way it makes sense, doesn't it? Like doing research. Once you've stated your thesis, you don't need all those little notes anymore, they are subsumed in the larger unifying rationale.

But now back to technology. A bunch of people have built this model of memory in software, calling it a "hierarchical temporal memory". It's an absolutely fascinating premise.

The appeal of London

November 22nd, 2008

London, it's a wonderful city. The culture, the entertainment, the architecture. Historical and contemporary at once. Everyone and everything is there.

Oh sure, initial impressions can be disappointing. The drab landmarks of postcard tourism.. the baroque London Bridge, the utterly pointless Tower of London, the entirely forgettable Buckingham Palace, the simplistically named Big Ben, the gaudy Westminster Abbey. Next to Rome or Paris they look almost barbaric, like the Stone Henge next to the Eiffel Tower. But I cannot for a second imagine that someone could come away from London without absorbing the magic and the culture inherent to it. There's something for everyone to love.

The most striking thing about London to outward appearances is the architecture. There is no shortage of classical buildings, but then there is none of modernity either. Soho, Picadilly, Westminster for a bite of classical; St. Paul's, Queen Victoria, Cornhill for the modern. But you don't have to chase it down, architecture is everywhere and the urbanism is top class, it all fits no matter what it is.

Walking around the wide streets there is that feeling of a real metropolis. The streets are buzzing, both motorized traffic and pedestrian. And they do not fall asleep after dark, there are always people. For that warm and cuddly city feeling Oxford Street is a good bet. When you're ready to take a load off, look for a Starbucks (they're everywhere). Then walk across the street to Caffè Nero, a cozy café chain without the fast food atmosphere.

If you're after shopping there is a huge Borders off Oxford Circus, 4 storeys of bookstore. Be there at 9am and you have the whole thing to yourself! And it's well worth it. Books have always been cheaper in England. You can walk out with two shopping bags for the price of a sports jersey or some silly fashion item.

London's subway system is unique and something of a contradiction. When you look at the map you notice that the stations cover the city very laboriously, it's obviously a huge network. But then you enter the underground and everything is so cramp, the passage ways are narrow, there's little space above your head, the platforms are about 4m wide, and the trains themselves are no different, only wide enough for 3 seats and a passage - less than a bus. So why is a network so vast, designed to transport so many people so cramped? And still, the trains run with such regularity that you're never actually obstructed or stalled, it's very efficient. The maximum waiting time in zone 1 is 3 minutes in the daytime.

State instituted paranoia

The one thing that everyone knows about London and Britain nowadays is that it's a surveillance society. I didn't actually take any pictures myself, but I bet I could cover every last site of interest just with the pictures taken for me and of me in every location. I'm not sure whom I have to call to recoup those photos, though. It's no exaggeration, there really is a camera everywhere, and often, several.

All of this for my protection, naturally. The subway is already entirely covered in cameras, but you'll still see signs reading "for your protection we are installing more cameras". Ditto in the commercial realm, the same cameras wrapped in tinted glass (so as to be less obvious) greet you in a café as the ones you see in the street.

London feels like a pretty safe place if it wasn't for the police crawling everywhere. I don't know about you, but seeing a police unit doesn't make me feel particularly safe. Presumably they are on scene to stop, intervene, apprehend, pursue and I don't want to get stuck with a ticket for crossing the street at my own choosing just because the restless cops feel they have to justify their presence somehow.

State instituted paranoia is on show. There's a warning sign on everything to alert you to the magnificent danger. Walking down Horse Guards Road in Westminster I saw an entirely unremarkable statue surrounded by a fence on all sides, with a plaque stating that it would be a criminal act to climb the fence. This kind of thing is systemic, there is so much distrust and hostility in the announcements and signage. A security circus.

The thing is though, I don't think the public is buying it. They are tolerating it, because it hasn't impacted their lives much, but London doesn't strike me as a society in anxiety or panic, far from it. London was the site of a bombing since the era of paranoia ensued, fair enough, but is the solution to that not police work rather than a paranoia epidemic? The public seems to think so. Terrorism is shamelessly used for political currency, as is the current trend. In the same area there's a monument to the Bali bombing victims. Not that Bali was unimportant, but how many other people have died tragically through various other causes in the same period, starting with the civilian casualties caused by the Iraq invasion (concentrate on the territories under British control, say), ending with the armed conflict du jour on the African continent? No political gain from that, so let's not dwell on those shall we.

Left is right, except when it's not

It is so typical of the British to be different. Not different in a useful way, just arbitrarily so. It might be illusions of grandeur over the long lost empire. One of those differences is driving on the other side of the road. Britain is part of a small minority of countries that drive on the left. To what end? Cars have to be built special for those markets. Traffic rules cannot be made universal worldwide. And for what? There is no trade-off to make, it's completely inconsequential which side you take. The only justification is "it must be this way because it's always been this way", which is a popular non-argument.

To the extent that motorized traffic works smoothly on the "left system", it also affects pedestrians. And in London there are some very clear signs that the left system isn't all that smooth. For starters, there's printing on the street at every pedestrian crossing, "look left", "look right", to tell us where the traffic is coming from. I've never seen this anywhere else, and it wouldn't be necessary if people understood how the traffic works.

You would expect that if the Brits are dedicated to the left system then everything would work accordingly. But it doesn't. When you're walking down the street on the right hand side, sometimes you're against the stream, sometimes with it. In the subway, where they have instructions for everything, they often have partitions in the middle of a walkway. In some places the sign says "keep left", in others "keep right". When you get to the escalator, you're supposed to stand on the right, and walk on the left, in blatant contradiction to the left system. The escalators themselves are flimsy on it, sometimes the one going up is on the right, sometimes it's on the left. Sometimes you're coming out of a walkway on the right and crossing over to the escalator on the left, clashing with the people coming down and switching to the right.

havenet: network perimeter test

November 17th, 2008

Network connections fail all the time, we've all been there. There are so many things that can go wrong, the network adapter driver can fail, the dhcp server can revoke the lease, the wifi router can disappear, the routing may be wrong at some point along the line, the dns server can be overloaded, or the remote host may be down. Those are some of the possibilities, and it can be quite a pain to track down the problem.

But the first thing to do is to figure out exactly what is working and what isn't. If you know that much then at least you know where to start. My goal here is to create a fairly simple test to examine the status of the network connection, leading up to a working internet connection. One constraint that I have is that I like it to be portable, so that I can carry it around along with my dotfiles. That means I would like it to work in any location just as long as I can get a shell, it should not require any dependencies.

A fully functional network connection looks like this:

What I do is try to detect the parameters of the network step by step, using the regular tools like route, ifconfig. Once I know what the hosts are, I do a ping. Now, a ping obviously isn't a foolproof test; if you're on a network that doesn't allow outgoing icmp then it's entirely possible that you can tcp out anyway. So what you really should do is tcp on port 80, not ping. But ping is extremely portable, whereas doing a tcp/udp probe is asking a lot more from the environment, needing something like nmap or hping.

Once you've established that the connection is working, and you want to know more about the network, you can go further with something like netscan.

The code is relatively stupid and messy, but that's the way bash is.

# Author: Martin Matusiak <numerodix@gmail.com>
# Licensed under the GNU Public License, version 3


function havenet {
	local init="$(toolsinit)"

	platforminit
	case "$PLATFORM" in
		"Linux")
			echo "Platform: $PLATFORM"
			run_havenet "$init";;
		*)
			echo "Platform: $PLATFORM (local network detection not supported)"
			run_haveinet "$init";;
	esac
}

function haveinet {
	local init="$(toolsinit)"
	platforminit
	echo "Platform: $PLATFORM"
	run_haveinet "$init"
}

function platforminit {
	if $(which uname &>/dev/null); then
		PLATFORM=$(uname 2>/dev/null)
	fi
}

function toolsinit {
	local tools="true"
	local missing=()


	local cmds=(/sbin/route /sbin/ifconfig ping nmap)
	local args=(" -n" "" " -c1 -W2" " -T3")
	local names=(route ifconfig ping nmap)

	local i=-1
	while [ $i -lt $(( ${#names[@]} - 1 )) ]; do i=$(( $i+1 ))
		if [ 0 -eq $(which ${cmds[$i]} &>/dev/null ; echo $?) ]; then
			tools="$tools;local ${names[$i]}=\"${cmds[$i]}${args[$i]}\""
		else
			missing[${#missing[@]}]="${cmds[$i]}"
		fi
	done


	if [ ${#missing[@]} -gt 0 ]; then
		echo -e "Missing tools: ${cred}${missing[*]}${creset}" 1>&2
	fi

	echo "$tools"
}

function run_havenet {

	eval "$@"

	local localranges="169.254 10 172.(1[6-9]|2[0-9]|3[0-1]) 192.168"


	### Scan networks
	
	echo -e "${cyellow} + Scanning for networks...${creset}"
	test=$($route 2>/dev/null | egrep "^[1-9]")
	if [[ $? != 0 ]]; then
		echo -e "    ${cred}none found${creset}"
	else
		local nets=$(echo "$test" | sort | awk '{ print $1 }')
		for net in $nets; do
			local gw=$($route 2>/dev/null | egrep "^$net" | awk '{ print $3 }')
			printf "    ${cgreen}%-15s${creset} ${ccyan}%s${creset}\n" "$net" "/ $gw"
		done

		### Detect ips

		local ips=
		for net in $nets; do
			local r=$(echo $net | sed "s/.0$//g" | sed "s/.0$//g" | sed "s/.0$//g")
			local ip=$($ifconfig 2>/dev/null | grep "inet addr:$r" | sed "s/inet addr:\([0-9.]*\).*$/\1/g")
			ips="$ip $ips"
		done

		echo -e "${cyellow} + Detecting ips...${creset}"
		test=$(echo "$ips" | egrep -v "^[ ]+$")
		if [[ $? != 0 ]]; then
			echo -e "    ${cred}none found${creset}"
		else
			local on_lan=1
			for ip in $ips; do
				printf "    ${cgreen}%-15s${creset}  %s" "$ip" "ping: "
				test=$($ping $ip 2>/dev/null)
				if [[ $? != 0 ]]; then
					echo -e "${cred}failed${creset}"
				else
					local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
					echo -e "${cgreen}$t ms${creset}"
				fi

				### Test ips for lan
				local ip_on_lan=0
				for prefix in $localranges; do
					test=$(echo "$ip" | egrep "^$prefix" 2>/dev/null)
					if [[ $? == 0 ]]; then
						ip_on_lan=1
					fi
				done
				on_lan=$(( $on_lan & $ip_on_lan ))
			done


			if [ $on_lan -eq 1 ]; then
				
				### Detect gateways if on lan

				echo -e "${cyellow} + Detecting gateways (network is local)...${creset}"
				test=$($route 2>/dev/null | grep UG)
				if [[ $? != 0 ]]; then
					echo -e "    ${cred}none found${creset}"
				else
					local gws=$(echo "$test" | awk '{ print $2 }')
					for gw in $gws; do
						printf "    ${cgreen}%-15s${creset}  %s" "$gw" "ping: "
						test=$($ping $gw 2>/dev/null)
						if [[ $? != 0 ]]; then
							echo -e "${cred}failed${creset}"
						else
							local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
							echo -e "${cgreen}$t ms${creset}"
						fi
					done

					### Try inet connection if we have a gateway 
					run_haveinet "$@"
				fi
			else

				### Try inet connection, we're on wan
				run_haveinet "$@"
			fi
		fi
	fi

}


function run_haveinet {

	eval "$@"

	local rootname="A.ROOT-SERVERS.NET."
	local rootip="198.41.0.4"
	
	local dnsport="53"

	local inethosts="yahoo.com google.com"
	local inetport="80"


	### Test inet connection

	echo -e "${cyellow} + Testing internet connection...${creset}"
	echo -en "    ${ccyan}$rootname  ${cgreen}$rootip${creset}   ping: "
	test=$($ping $rootip 2>/dev/null)
	if [[ $? != 0 ]]; then
		echo -e "${cred}failed${creset}"
	else
		local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
		echo -e "${cgreen}$t ms${creset}"
	fi

	### Detect dns

	echo -e "${cyellow} + Detecting dns servers...${creset}"
	test=$(cat /etc/resolv.conf 2>/dev/null | grep ^nameserver)
	if [[ $? != 0 ]]; then
		echo -e "    ${cred}none found${creset}"
	else
		local dnss=$(echo "$test" | awk '{ print $2 }')
		for dns in $dnss; do
			printf "    ${cgreen}%-15s${creset}  %s" "$dns" "ping: "
			test=$($ping $dns 2>/dev/null)
			if [[ $? != 0 ]]; then
				echo -en "${cred}failed${creset}"
			else
				local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
				echo -en "${cgreen}$t ms${creset}"
			fi


			local proto="tcp" ; local udpflags=""
			if [[ `whoami` = "root" ]]; then
				proto="udp"; udpflags="-sU -PN"
			fi
			echo -en "  dns/$proto: "
			test=$($nmap $dns $udpflags -p $dnsport 2>/dev/null)
			if ! echo "$test" | grep "$dnsport/$proto" | grep "open" &>/dev/null; then
				echo -e "${cred}failed${creset}"
			else
				local t=$(echo "$test" | grep "scanned in" | sed "s/^.*in \([0-9.]*\) seconds.*$/\1/g")
				t=$(echo $t*1000 | bc)
				echo -e "${cgreen}$t ms${creset}"
			fi
		done
	fi

	### Test inet dns

	echo -e "${cyellow} + Testing internet dns...${creset}"

	for inethost in $inethosts; do
		printf "    ${cgreen}%-15s${creset}  %s" "$inethost" "ping: "
		test=$($ping $inethost 2>/dev/null)
		if [[ $? != 0 ]]; then
			echo -en "${cred}failed${creset}"
		else
			local t=$(echo "$test" | grep "min/avg" | sed "s/.*= \([0-9.]*\)\/.*$/\1/g")
			echo -en "${cgreen}$t ms${creset}"
		fi

		echo -en "  http: "
		test=$($nmap $inethost -p $inetport 2>/dev/null)
		if ! echo "$test" | grep "$inetport/tcp" | grep "open" &>/dev/null; then
			echo -e "${cred}failed${creset}"
		else
			local t=$(echo "$test" | grep "scanned in" | sed "s/^.*in \([0-9.]*\) seconds.*$/\1/g")
			t=$(echo $t*1000 | bc)
			echo -e "${cgreen}$t ms${creset}"
		fi
	done

}

UPDATE: Replacing with newer version that is a bit more clever.

UPDATE2: Added tool detection and platform detection.

Chuck: properly farsical

November 15th, 2008

A lot of really bad "comedy" movies have been made to portray the despair of suburbia. People whose lives revolve around work in a big supermarket or other chain, empty most of the time, so they try to find something, anything, to distract themselves from the daily routine.

The premise for Chuck is the same. He's a geek, he has a pity-friend geekier than him. He works at a big electronics chain. And he has a "normal" sister who wants him to be "normal".

Then it happens. His old college buddy, a CIA agent gone rogue, sends him a message containing every government secret he's stolen in his "rogueness". Chuck somehow absorbs the whole thing, the computer breaks, and now he's the only one with the secrets. Except he's still the geeky suburbia guy, so two agents from competing agencies show up to make sure nothing "happens" to him. Needless to say, he cannot divulge anything to his sister or his friend, so he has to pretend like nothing has changed. The agents, in turn, get jobs near him and have to fit into the suburban landscape.

You're probably thinking "with a premise like that it could so easily suck". And I'm with you. But it doesn't. Chuck is pretty good in his role, and the whole spying thing is sufficiently farsical to be funny, but not so overdone that it's stupid.

what's in a fixed point?

November 9th, 2008

The fixed point is a very intuitive idea that we know from daily life. It's the notion that if something is a certain way, and you do something to change it, it will change. Some things you can go on changing forever by repeating the same action, but other things reach a limit beyond which repeating the action has no effect. Suppose you are going 50km/h in your car and you step on the brake. The car slows down. You step on the brake again, the car slows down again. But eventually the car will have come to a complete stop and stepping on the brake doesn't do anything anymore. The point at which the action has no effect anymore has a scary math name: a fixed point.

It's easy enough to write a function that finds the fixed point of another function f. You apply f to the argument and you get a value, you apply f to that and you get a value, you apply f to that and you get a value etc. And every time you check if the new value is different from the old. (Or even if it's just sufficiently similar, Newton-Raphson says hello.) Here is how it goes:

fixfinder :: (Eq a) => (a -> a) -> a -> a
fixfinder f arg =
    let val = f arg
    in if val == arg
        then arg
        else (fixfinder f val)

{-
*Main> fixfinder sqrt 68
1.0
-}

We can try it on a function whose fixed point we know, like the square root. Back in school, did you ever hit the square root key on your calculator repeatedly out of shear boredom? Eventually you'd get 1. (You can also take the square root of 0 and get 0, the second fixed point, but that's not particularly exciting.)

So far so good, now comes the mysterious part. The fixed point idea exists in programming, but in a different guise. In Data.Function there is a function called fix. It makes a very odd promise: to find the fixed point of a function without using a value. Que? How can you return the fixed point value (leaving aside for the moment the question of how you can even calculate it) if you don't have a single value to begin with? Heck, without an input value you don't even know what type the output is, if f is a polymorphic function.

fix :: (a -> a) -> a
fix f = f (fix f)

{-
*Main> fix sqrt
*** Exception: stack overflow
-}

The function doesn't look promising at all. It applies f, but there is no termination condition. Once you reach the fixed point (if there is one), how do you stop? It obviously can't figure out the square root function.

It turns out that fix is a trick used to perform recursion in languages that don't have a recursion primitive (ie. the compiler reaches an expression containing the name of the function in its own body and doesn't know what to do). The trick is that you write a function expecting among other things, a function argument (fix). Then, at the point in your function where you need to recurse, you call fix. Fix then calls the function back, so it's a sort of mutual recursion. In pure lambda calculus fix is called the y-combinator. The formula is so ridiculously cryptic that some have taken to tattoo it on their arms, obviously given up on remembering.

So what do you get out of it? Solely the fact that you get around calling the function within itself, from what I can see. And clearly that's all it does too. How do you prevent the seemingly inevitable infinite loop? You put the termination condition in your semantic function. So you write your recursive function exactly the same, but you give it an extra argument, fix. Then, at the point of recursion, instead of calling the function, you call fix. It's so bizarre that I've written out the evaluation sequence to shed some light on it.

Daredevil that I am, I'm using the factorial function. What's happening here, supposedly, is that fix is computing the fixed point of fac. We can then take that result and apply it to a number, it finds the factorial, it doesn't diverge.

What's happening here? It looks like a sort of loop unrolling, which can clearly proceed ad infinitum, were it not for Haskell's lazy nature. And, one can speculate, it's unrolling the recursion exactly the number of times it needs to be expanded (but then again, evaluation with a value already does that), but how could you possibly know that before you have a value to calculate with? It's not actually computing anything, is it? How is this any different from any old recursive function?

What fac really does is take one step toward the factorial. Multiply one factor, then call fix, which calls fac again. Eventually, the termination condition within fac kicks in. But that doesn't mean we've found the fixed point of fac, which is fac(1) = 1 and fac(2) = 2.  In fact, it seems to me we're walking right past these two fixed points, and calling fac one last time with n=0, because how else can fac terminate?

There is a lot more to fixed points, there's even something called a fixed point datatype that my small brain completely fails to comprehend. The most sane description on fix that I found is in the Haskell Book if you want to take a look. I wish you luck.