Fishtrap

php and other stuff I know

Zooming in on the Mandlebrot set

25 September 2011 by nat | 0 comments

Here’s a video I showed a couple of times while talking about escape time fractals in PHP. The video was made by using PHP to generate the mandlebrot set set centred on a point and the decreasing the scale logarithmically.

httpv://www.youtube.com/watch?v=8pAUIWYVXXM

12 August 2011
by nat
0 comments

CURL less POST requests in PHP

Libcurl is a great library with a whole host of features. In PHP it is accessible with the php_curl extension. Although it’s fully features it has a rather ugly and clumsy api. Added to this php_curl is often not part of the default install of PHP.

There is another option. In PHP you probably know you can do requests with the streams extension and use functions like file_get_contents to retrieve a url contents.

<?php
$page = file_get_contents('http://fishtrap.co.uk');

Since PHP 5.0 you can also set a stream_context to include POST data. This can include files and other multipart form data.

I created a short script to try add a more intuitive and usable wrapper around the functions. To use it you just need to do:

<?php
include('StreamsHttpPost.php');
$request = new StreamsHttpPost('http://example.com');
$data = array(
'foo' => 'bar',
'baz' => 'bat',
);
$request->addFile('picture',  'path/to/file');
$page = $request->post($data);
var_dump($request->getResponseCode()); // int(302)

This will then send a post request as if the user had submitted a form with the form fields.

The code is here on github. Comments, pull requests and corrections welcome.

1 August 2011
by nat
0 comments

Borwein’s algorithm for Π a PHP implementation

One of the joys of Maths is the fact that the names for things sound impressive add to that the fact that the notation can look very off putting if you you don’t know what it says and this has the effect of making you seem very erudite when talking about it. With this in mind I thought I’d post a quick implementation of Borwein’s algorithm for convergance on Π.

The generation of increasing digits of Π is in itself completely pointless but makes an interesting area of research for mathematicians and computer scientists with parallel advances in algorithm and hardware. PHP is possibly the least suitable language to implement these computationally intense calculations. However, it is possible for todays PHP scripts to quickly generate digits that took hours of computing time in the 1950′s and 1960′s.  Borwein’s algorithm is interesting for the increasing number of correct digits it gives with each iteration. According to wikipedia the algorithm is given by starting out with:

 \begin{align} a_0 & = 6 - 4\sqrt{2} \\                       y_0 & = \sqrt{2} - 1         \end{align}

And then iterating

 \begin{align} y_{k+1} & = \frac{1-(1-y_k^4)^{1/4}}{1+(1-y_k^4)^{1/4}} \\                        a_{k+1} & = a_k(1+y_{k+1})^4 - 2^{2k+3} y_{k+1} (1 + y_{k+1} + y_{k+1}^2)           \end{align}


function borwein($precision){
	// set scale with suitable spare room
	bcscale($precision+5);

	//inital conditions
	$rootTwo = bcsqrt(2);
	$a = bcsub(6, bcmul(4, $rootTwo));
	$y = bcsub($rootTwo, 1);

	//number of interations needed
	$count = floor(log($precision)/log(4));
	for($k = 0; $k < $count; $k++){
		$sqrt = bcsqrt(bcsub(1,bcpow($y, 4)));
		$right = bcsqrt($sqrt);
		$top = bcsub(1, $right);
		$bottom = bcadd(1, $right);
		$y = bcdiv($top, $bottom);

		$onePlusY = bcadd(1, $y);
		$left = bcmul($a, bcpow($onePlusY, 4));
		$y2 = bcpow($y, 2);
		$power = bcpow(2, (2*$k+3));
		$expansion = bcadd($onePlusY, $y2);
		$right = bcmul($power, bcmul($y, $expansion));
		$a = bcsub($left, $right);
	}
return bcdiv(1, $a, $precision);
}
echo borwein(2037), PHP_EOL;

9 July 2011
by admin
0 comments

Factorial class

Earlier in the week i started experimenting with translating infinite series calculations for the value of Π into php. I started with the Chudnovsky brothers algorithm which I understood to be the fastest.

As you will see extensive use of factorials is made. I was using the bc extension for PHP which does not have a simple way of calculating factorials. I came up with the following class to try and calculate them efficiently from the nearest previously calculated. Using it I was able to cut the calculation time for 2037 digits in half.

<?php

class Factiorial {

	private static $_cache = array(1 => 1);

	public function calculate($n) {
		$nearest = $this->findNearestInCache($n);
		$answer = self::$_cache[$nearest];
		$diff = $n - $nearest;
		if ($diff > 0) {
			for ($i = $nearest; $i < $n; ++$i) {
				$answer = bcadd($answer, bcmul($answer,$i));
				self::$_cache[$i+1] = $answer;
			}
		} else {
			for ($i = $nearest; $i > $n; --$i) {
				$answer = bcdiv($answer,$i);
			}
		}
		return $answer;
	}

	private function findNearestInCache($n) {
		$keys = array_keys(self::$_cache);
		rsort($keys);
		$nearest = current($keys) ;
		$smallestDiff = abs(current($keys) - $n);
			foreach ($keys as $key) {
				if ($diff = abs($n - $key) < $smallestDiff) {
					$nearest = $key;
					$smallestDiff = $diff;
				}
			}
			return $nearest;
	}
}

This only really works because we are calculating successive factorials and will often be calculating the same value several times. Having arrays of several thousand items in the cache could be quite slow so I tried limiting the size of the cache array but the extra bookkeeping overhead proved to slow the script down.

16 June 2011
by nat
14 Comments

Compiling PHP to use mysqlnd on ubuntu

Distro maintainers seem to be a little slow in using mysqlnd. I guess they have their own ideas and needs.

The best way I’ve found of installing mysqlnd on ubuntu is to use dpkg to rebuild the .deb. Of course this will need to be done when ever you update the PHP package so is not recomended for anything other than experimental servers.

Quick step by step

Install everything needed to compile C code

sudo apt-get install build-essential debhelper

Install any special depandancies for building PHP such as bison

sudo apt-get build-dep php5

Install the PHP source for the current PHP package

sudo apt-get source php5

This will download the source code for your PHP version into the current directory

cd php5-5.3.2/

Then edit the file debian/patches/series or in older ubuntu releases debian/patches/order

sudo vim debian/patches/series

remove the lines
force_libmysqlclient_r.patch
and while we’re at it remove this line which removes the config flags from phpinfo() apparently done by debian to stop false bug reports but quite annoying
052-phpinfo_no_configure.patch

then edit the rules file

sudo vim debian/patches/rules

sudo vim debian/rules

search for
–with-mysql=shared, /usr \
replace with
–with-mysql=mysqlnd \

same with
–with-mysqli=shared, /usr \
replace with
–with-mysqli=mysqlnd \

make –enable-pdo=shared or –with-pdo=shared \

into –with-enable or –with-pdo

and
–with-pdo-mysql=shared, /usr \
into
–with-pdo-mysql=mysqlnd \

This will build mysql as a static module rather than load it dynamically this will save building each mysql extension separately with mysqlnd

stop the tests running by exporting an environment variable

export DEB_BUILD_OPTIONS=nocheck

Now build the package

sudo dpkg-buildpackage

Go and do something else for a little while.

Once done if you

cd ..
ls

You should see a big list of debs

dpkg the ones you need such as

sudo dpkg -i php5-common_5.3.2-1ubuntu4.9_amd64.deb
sudo dpkg -i libapache2-mod-php5_5.3.2-1ubuntu4.9_amd64.deb

bingo the output of phpinfo() and php -m should confirm you have mysqlnd installed