Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to translate this Math Formula in Haskell or Python? (Was translated in PHP)

I'm trying to convert a Math Formula into PHP code.

You can see the formula in the accepted answer here: Applying a Math Formula in a more elegant way (maybe a recursive call would do the trick).

I'm not a professional coder so I'm trying my best to translate it but my skills are limited and I've encountered several problems.

Let's start.

There's a vector containing players' stacks: I think a bidimensional array should do the work here. I'd add a key to identify each player.

$array = array(1 => 2000, 3 => 5000 ...);

Now he wants to create a Matrix of values, I did my researches and found a PEAR package called Math_Matrix, installed it but I'm wondering how to create that sort of matrix.

I'm worried that I won't be able to translate the entire code because he uses advances methods like recursive calls etc.

Could you help me?

EDIT: OLD BOUNTY REWARD

I tried what you've suggested but I feel like wasting my time because of my poor-programming skills.

I'VE DECIDED TO OFFER A 50 BOUNTY IF SOMEONE WANTS TO HELP ME BY TRANSLATING THAT FORMULA IN PHP.

Note that if you think that translating in Python is easier/more suitable/other, please provide me a way to include the Python script inside a PHP script since I'm planning to use this formula in a website.

like image 834
Giorgio Avatar asked Dec 22 '11 14:12

Giorgio


1 Answers

Here you go.

I place this code into the public domain.

# Function to make an array of 'width' zeros
function makerow($width){
 $row=array();
 for($x=0;$x<$width;$x++){
   $row[$x]=0;
 }
 return $row;
}

# Function to make a width*height matrix
function makematrix($width,$height){
 $matrix=array();
 for($y=0;$y<$height;$y++){
  $matrix[$y]=array();
  for($x=0;$x<$width;$x++){
   $matrix[$y][$x]=0;
  }
 }
 return $matrix;
}

# Adds one matrix to another
function matrixadd(&$matrixdest,&$matrixsrc){
 for($i=0;$i<count($matrixdest);$i++){
  for($j=0;$j<count($matrixdest[$i]);$j++){
   $matrixdest[$i][$j]+=$matrixsrc[$i][$j];
  }
 }
}

# Multiplies a matrix by a scalar
function matrixmultiply(&$matrix,$scalar){
 for($i=0;$i<count($matrix);$i++){
  for($j=0;$j<count($matrix[$i]);$j++){
   $matrix[$i][$j]*=$scalar;
  }
 }
}

# Calculates the equity of each place. Rows indicate players;
# columns indicate places (0 is 1st place, 1 is second, and so on)
# The parameter 'places' is optional.  If not given, uses the 
# number of stacks.
function equitymatrix(&$stacks, $places=-1){
 if($places==-1){
  # replace places with the stack count
  $places=count($stacks);
 }
 if(count($stacks)<=1){
  return array(array(1));
 }  
 $totalStacks=0;
 for($i=0;$i<count($stacks);$i++){
  $totalStacks+=$stacks[$i];
 }
 # Optimize for case where there is only one place
 if($places==1){
  $matrix=makematrix(1,count($stacks));
  for($i=0;$i<count($stacks);$i++){
   $matrix[$i][0]=$stacks[$i]*1.0/$totalStacks;
  }
  return $matrix;
 }
 # Optimize for case where there are two places
 if($places==2){
  $matrix=makematrix(2,count($stacks));
  for($i=0;$i<count($stacks);$i++){
   $matrix[$i][0]=$stacks[$i]*1.0/$totalStacks;
  }
  for($i=0;$i<count($stacks);$i++){
   for($j=0;$j<count($stacks);$j++){
    if($i!=$j){
     $matrix[$i][1]+=$matrix[$j][0]*($stacks[$i]*1.0/($totalStacks-$stacks[$j]));
    }
   }
  }
  return $matrix;
 }
 # Calculate the probabilities of each player getting first place
 $probabilities=array();
 for($i=0;$i<count($stacks);$i++){
  $probabilities[$i]=$stacks[$i]*1.0/$totalStacks;
 }
 #echo(count($stacks)." ".$places."\n");
 $subequities=array();
 for($i=0;$i<count($stacks);$i++){
  $substacks=array();
  # Assume that player i would be in first place
  # Create a new array with i's stack removed
  for($j=0;$j<count($stacks);$j++){
   if($j!=$i){
    array_push($substacks,$stacks[$j]);
   }
  }
  # Find the subequity of the remaining players
  $subequities[$i]=equitymatrix($substacks,
    min($places,count($substacks)));
  for($j=0;$j<count($subequities[$i]);$j++){
   array_unshift($subequities[$i][$j],0);
  }
  # Add player i back
  $newrow=makerow($places);
  $newrow[0]=1;
  array_splice($subequities[$i],$i,0,array($newrow));
 }
 $equities=makematrix($places,count($stacks));
 for($i=0;$i<count($stacks);$i++){
  # Multiply the probabilities
  matrixmultiply($subequities[$i],$probabilities[$i]);
  # Add the subequity
  matrixadd($equities,$subequities[$i]);
 }
 return $equities;
}

Example:

$mystacks=array(10,40,30,20);
print_r(equitymatrix($mystacks));

As to the use of matrices:

In PHP, a matrix can be represented as an array of arrays. You can see that in the function makematrix, which returns an array of length height, with each element being an array of width zeros. Your problem uses the following matrix operations, both of which are simple:

  • Adding two matrices (matrixadd). Here, just add the elements of one matrix to the corresponding elements of the other matrix.
  • Multiplying a matrix by a single number (a scalar) (matrixmultiply) simply involves multiplying each element of the matrix by that number.
like image 113
Peter O. Avatar answered Nov 10 '22 10:11

Peter O.