Как перевести эту математическую формулу в Haskell или Python? (Был переведен на PHP)

Я пытаюсь преобразовать математическую формулу в PHP-код.

Вы можете увидеть формулу в принятом ответе здесь: Применять математическую формулу более элегантным способом (возможно, рекурсивный вызов будет делать трюк) .

Я не профессиональный кодер, поэтому я стараюсь перевести его, но мои навыки ограничены, и я столкнулся с несколькими проблемами.

Давайте начнем.

Есть вектор, содержащий стопки игроков: я думаю, что двумерный массив должен делать здесь работу. Я бы добавил ключ, чтобы идентифицировать каждого игрока.

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

Теперь он хочет создать матрицу значений, я сделал свои исследования и нашел пакет PEAR под названием Math_Matrix, установил его, но мне интересно, как создать такую ​​матрицу.

Я беспокоюсь, что не смогу перевести весь код, потому что он использует методы продвижения, такие как рекурсивные вызовы и т. Д.

Не могли бы вы помочь мне?

РЕДАКТИРОВАТЬ: СТАРЫЙ БОЙНТ

Я попробовал то, что вы предложили, но я чувствую, что трачу свое время из-за моих навыков плохого программирования.

Я РЕШИЛ ПРЕДЛОЖИТЬ 50 BOUNTY, ЕСЛИ КОГДА-ЛИБО ХОЧЕТ ПОМОЧЬ МЕНЯ, ПЕРЕВЕСТИ, ЧТО ФОРМУЛА В PHP.

Обратите внимание: если вы считаете, что перевод на Python проще / более подходящим / другим, предоставьте мне способ включить скрипт Python внутри скрипта PHP, поскольку я планирую использовать эту формулу на веб-сайте.

Ну вот.

Я помещаю этот код в общедоступное.

 # 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; } - # 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; } 

Пример:

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

Что касается использования матриц:

В PHP матрица может быть представлена ​​как массив массивов. Вы можете видеть это в функции makematrix , которая возвращает массив длины длины, причем каждый элемент представляет собой массив нулей width . В вашей задаче используются следующие матричные операции, обе из которых просты:

  • Добавление двух матриц ( matrixadd ). Здесь просто добавьте элементы одной матрицы к соответствующим элементам другой матрицы.
  • Умножение матрицы на один номер (скаляр) ( matrixmultiply ) просто включает в себя умножение каждого элемента матрицы на это число.

Я думаю, самый большой вопрос в том, что вы планируете использовать для этого. В конце концов, я бы рекомендовал не использовать PHP. Он не предназначен для такого типа работы, и вы в конечном итоге причиняете много работы для себя позже.

Если вы просто ищете способ его вычисления, я бы рекомендовал использовать Octave (версия OpenSource для MATLAB). Если вы действительно хотите создать вокруг нее программу, вы должны изучить Python с помощью модуля NumPy: http: // numpy .scipy.org /


Если у вас есть такая возможность, я бы рекомендовал использовать mod_python для запуска NumPy, чтобы справиться с этим. Вероятно, это будет самый простой способ сделать это, поскольку NumPy может обрабатывать Matrices. Если учесть это, вы должны посмотреть на следующие классы, которые существуют для обработки матриц в PHP. Некоторые люди разработали несколько классов, разработанных специально для манипулирования матрицами.

http://www.phpkode.com/scripts/item/matrix-new/ http://www.phpclasses.org/package/2859-PHP-Perform-operations-with-matrices.html

Если у вас установлен Matlab, с символическим набором инструментов математики,

вы можете использовать функцию ccode , чтобы перевести эту формулу (или любую другую) в c-код (который очень похож на php).