PHP equation from JavaScript - php

I have this JavaScript equation which I'm now trying to transform to PHP.
JavaScript:
LVL=new Array();
LVL[1]=128;
LVL[0]=128;
m=.05;
for (i=1;i<101;i++) {
if (i>1) {
LVL[i]=Math.floor(LVL[i-1]+(LVL[i-1]*m));
m=m+.0015;
}
}
then it's a bunch of document.writes of a table and a for loop.
Here's what I have so far (which is NOT working):
<?php
$n = 1; // level
$m = .05; // exp modifier
$exp = floor($n*1+($n-1)*$m);
echo "Level " . $n . ", exp needed: " . $exp; // 128 exp
?>
The PHP output is: Level 1, exp needed: 1 and that's WRONG.
It SHOULD say: Level 1, exp needed: 128
What am I doing wrong?

A direct transcription:
$LVL = array();
$LVL[1] = 128;
$LVL[0] = 128;
$m = .05;
for ($i = 1; $i < 101; $i++)
{
if ($i > 1)
{
$LVL[$i] = floor($LVL[$i-1] + $LVL[$i-1]*$m);
$m = $m + .0015
}
}
You need to build the array as its built bottom-up

You do a couple of errors:
you use the index (the level) as it is the amount of the experience points needed to
reach the level.
you forgot the for (if you are testing the formula it is ok)
the code so far:
$lvl = array(128,128);
$modifier=.05;
for ($i=1;$i<101;i++) {
$lvl[$i]=floor($lvl[$i-1]*(1+$modifier));
$modifier+=0.0015;
}
foreach ($lvl as $level=>$points) {
echo "Level " . $level . ", exp needed: " . $points ."\n<br />"; // 128 exp
}

Related

Basic perceptron for AND gate in PHP, am I doing it right? Weird results

I'd like to learn about neural nets starting with the very basic perceptron algorithm. So I've implemented one in PHP and I'm getting weird results after training it. All the 4 possible input combinations return either wrong or correct results (more often the wrong ones).
1) Is there something wrong with my implementation or the results I'm getting are normal?
2) Can this kind of implementation work with more than 2 inputs?
3) What would be the next (easiest) step in learning neural nets after this? Maybe adding more neurons, changing the activation function, or ...?
P.S. I'm pretty bad at math and don't necessarily understand the math behind perceptron 100%, at least not the training part.
Perceptron Class
<?php
namespace Perceptron;
class Perceptron
{
// Number of inputs
protected $n;
protected $weights = [];
protected $bias;
public function __construct(int $n)
{
$this->n = $n;
// Generate random weights for each input
for ($i = 0; $i < $n; $i++) {
$w = mt_rand(-100, 100) / 100;
array_push($this->weights, $w);
}
// Generate a random bias
$this->bias = mt_rand(-100, 100) / 100;
}
public function sum(array $inputs)
{
$sum = 0;
for ($i = 0; $i < $this->n; $i++) {
$sum += ($inputs[$i] * $this->weights[$i]);
}
return $sum + $this->bias;
}
public function activationFunction(float $sum)
{
return $sum < 0.0 ? 0 : 1;
}
public function predict(array $inputs)
{
$sum = $this->sum($inputs);
return $this->activationFunction($sum);
}
public function train(array $trainingSet, float $learningRate)
{
foreach ($trainingSet as $row) {
$inputs = array_slice($row, 0, $this->n);
$correctOutput = $row[$this->n];
$output = $this->predict($inputs);
$error = $correctOutput - $output;
// Adjusting the weights
$this->weights[0] = $this->weights[0] + ($learningRate * $error);
for ($i = 0; $i < $this->n - 1; $i++) {
$this->weights[$i + 1] =
$this->weights[$i] + ($learningRate * $inputs[$i] * $error);
}
}
// Adjusting the bias
$this->bias += ($learningRate * $error);
}
}
Main File
<?php
require_once 'vendor/autoload.php';
use Perceptron\Perceptron;
// Create a new perceptron with 2 inputs
$perceptron = new Perceptron(2);
// Test the perceptron
echo "Before training:\n";
$output = $perceptron->predict([0, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([0, 1]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 1]);
echo "{$output} - " . ($output == 1 ? 'correct' : 'nope') . "\n";
// Train the perceptron
$trainingSet = [
// The 3rd column is the correct output
[0, 0, 0],
[0, 1, 0],
[1, 0, 0],
[1, 1, 1],
];
for ($i = 0; $i < 1000; $i++) {
$perceptron->train($trainingSet, 0.1);
}
// Test the perceptron again - now the results should be correct
echo "\nAfter training:\n";
$output = $perceptron->predict([0, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([0, 1]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 0]);
echo "{$output} - " . ($output == 0 ? 'correct' : 'nope') . "\n";
$output = $perceptron->predict([1, 1]);
echo "{$output} - " . ($output == 1 ? 'correct' : 'nope') . "\n";
I must thank you for posting this question, I have wanted a chance to dive a little deeper into neural networks. Anyway, down to business. After tinkering around and verbose logging what all is happening, it ended up only requiring 1 character change to work as intended:
public function sum(array $inputs)
{
...
//instead of multiplying the input by the weight, we should be adding the weight
$sum += ($inputs[$i] + $this->weights[$i]);
...
}
With that change, 1000 iterations of training ends up being overkill.
One bit of the code was confusing, different setting of weights:
public function train(array $trainingSet, float $learningRate)
{
foreach ($trainingSet as $row) {
...
$this->weights[0] = $this->weights[0] + ($learningRate * $error);
for ($i = 0; $i < $this->n - 1; $i++) {
$this->weights[$i + 1] =
$this->weights[$i] + ($learningRate * $inputs[$i] * $error);
}
}
I don't necessarily understand why you chose to do it this way. My unexperienced eye would think that the following would work as well.
for ($i = 0; $i < $this->n; $i++) {
$this->weight[$i] += $learningRate * $error;
}
Found my silly mistake, I wasn't adjusting the bias for each row of a training set as I accidentally put it outside the foreach loop. This is what the train() method should look like:
public function train(array $trainingSet, float $learningRate)
{
foreach ($trainingSet as $row) {
$inputs = array_slice($row, 0, $this->n);
$correctOutput = $row[$this->n];
$output = $this->predict($inputs);
$error = $correctOutput - $output;
// Adjusting the weights
for ($i = 0; $i < $this->n; $i++) {
$this->weights[$i] += ($learningRate * $inputs[$i] * $error);
}
// Adjusting the bias
$this->bias += ($learningRate * $error);
}
}
Now I get the correct results after training each time I run the script. Just 100 epochs of training is enough.

How do I divide an integer over multiple values in PHP?

I'm trying to make a little PHP script for fun, and I'm a little stuck.
I want to divide an integer (for example 5) over multiple values.
For example:
$total = 5;
$mike = 0;
$ralf = 0;
$ashley = 0;
// Run the magic here
echo "Mike has " . $mike . " apples, Ralf has " . $ralf ." apples and Ashley has " . $ashley . " apples";
The output that I expect would look something like this:
Mike has 2 apples, Ralf has 1 apples and Ashley has 2 apples
Is there a way how to do this? :)
I can't do this hard coded, because I want the values to be randomized.
Cheers
Do it like this:
$total = 5;
$mike = rand(1,$total-2); // so that max value is 3 (everyone should get at least 1) ($total - $numberOfVarsToDistributeTheValueTo + 1)
$ralf = rand(1,$total - $mike - 1); // if 3 goes to mike, only 1 goes to ralf
$ashley = $total - $mike - $ralf; // i hope you understand.
// use it.
Something like this would work:
$people = array('mike','ralf','ashley');
$num = count($people);
$sum = 5; // TOTAL SUM TO DIVIDE
$groups = array();
$group = 0;
while(array_sum($groups) != $sum) {
$groups[$group] = mt_rand(0, $sum/mt_rand(1,5));
if(++$group == $num){
$group = 0;
}
}
// COMBINE ARRAY KEYS WITH VALUES
$total = array_combine($people, $groups);
echo "Mike has " . $total['mike'] . " apples, Ralf has " . $total['ralf'] ." apples and Ashley has " . $total['ashley'] . " apples";
Solution is inspired from this answer: https://stackoverflow.com/a/7289357/1363190
Hope This function will do your work . it can work for variable # of persons also.
divide_items(10,['mike','ralf','ashley']);
function divide_items($total=1,array $persons){
$progressed = 0;
for($i=0;$i<count($persons);$i++){
echo $random_count = rand(1,$total);
if(($i==(count($persons)-1)) && $progressed<$total ){
$random_count1 =$total - $progressed;
echo $persons[$i]." has ".$random_count1 ." Items<br>";
continue;
}
$progressed = $progressed+$random_count;
if($progressed<=$total){
echo $persons[$i]." has ".$random_count ." Items<br>";
}else{
echo $persons[$i]." has 0 Item<br>";
}
$total = $total-$random_count;
$progressed = 0;
}
}

Array counting with different keys

What I need is putting this array in a loop, but I can't get it to work because week is 1 - 9 and the key is 0 - 8. So i getting a error with a undefined offset i know why the does that but I don't know how to do this properly.
Before people ask me why not just change week1 to week0 and start counting from there. I can't because I did a calculating that is based on 1 - 52 and it will mess up my calculating if I start on 0 - 51
$totaal_vruchtzetting_week[10] = $totaal["week1"][0] + // = 0.46
$totaal["week2"][1] + // = 2.87
$totaal["week3"][2] + // = 4.97
$totaal["week4"][3] + // = 4.35
$totaal["week5"][4] + // = 3.02
$totaal["week6"][5] + // = 2.03
$totaal["week7"][6] + // = 1.41
$totaal["week8"][7] + // = 1.12
$totaal["week9"][8]; // = 1.13
// Should be total 21,36
Edit:
This is my loop I got until now but it gives me the wrong answer plus 2 errors
for($week = 1; $week < 9; $week++)
{
for($sw = 0; $sw <= 8; $sw++)
{
$totaal_vruchtzetting_week[10] += $totaal["week".$week][$sw];
}
}
echo $totaal_vruchtzetting_week[10]; // Outputs 170.89
$i=1;
$totaal_vruchtzetting_week[10]=0;
foreach($totaal as $total)
{
$totaal_vruchtzetting_week[10]+=$total["week$i"][$i-1];
$i++;
}
echo $totaal_vruchtzetting_week[10];
You should sum with this this loop
$i = 1;
$result = 0;
for ($i = 1; $i <= 9; $i++) {
if (isset($totaal['week' . $i]) && isset($totaal['week' . $i][$i - 1])) {
$result += floatval($totaal['week' . $i][$i - 1]);
}
}
$totaal_vruchtzetting_week[10] = $result;
$sum = 0;
foreach(array_values($totaal) as $index=>$item)
$sum += reset($item);
echo $sum; // 21.36
$totaal_vruchtzetting_week[10] = $sum;
Demo
Not sure if I got your question, but did you consider foreach? It iterates over every array regardless of the keys.

how do i sum two variables in for each loop or while or for loop

is that possible to sum variable static values in the while or for loop? i have code and working on it but it sum variables only one time?
Here My Code
session_start();
$length=count($_SESSION['product1']);
$shipping2='280';
$shipping3='680';
$newshipping='0';
$newshipping1='0';
$i='0';
while($i= <$length)
{
$newshipping=$shipping2+$shipping3;
$newshipping1=$newshipping+$shipping2;
}
For Example I want like this
$shipping2='280'; should be sum with every result of $newshipping1
`$newshipping1`= $shipping2='280' + $shipping3='680' = `$newshipping1`=960
+ $shipping2='280'??
'$newshipping1`=960+ $shipping2=280+ $shipping2=280+ $shipping2=280 .....
when ever new product1 enter it should be add $shipping2=280
in the result of `$newshipping1`
I have completed my code here my final code
$length=count($_SESSION['product1']);
$shipping2=280;
$shipping3=680;
$newshipping=0;
for($i=0; $i <$length; $i++) {
if($i == 1) {
$newshipping = $shipping2+$shipping3;
} else if($i <= 100) {
$newshipping = $newshipping+$shipping2;
}
}
Your logic seems a bit confusing, however you can sum several integers. If you are trying to figure out the final amount of several iterations you should:
$shipping_one = 680;
$shipping_two = 260;
$shipping_three = 0;
$finalShipping = array();
while($i= <$length)
{
$finalShipping[] = $shipping_one + $shipping_two + $shipping_three;
}
$finalTotal = array_sum($finalShipping);
If you can clarify your question, I can clarify my answer.
this will be ((680) + (4 * 280)) like you explained in your last comment.
$length = 1;
echo "Test with $length : ".getShippingTotal($length)." <br />";
$length = 2;
echo "Test with $length : ".getShippingTotal($length)." <br />";
$length = 3;
echo "Test with $length : ".getShippingTotal($length)." <br />";
$length = 4;
echo "Test with $length : ".getShippingTotal($length)." <br />";
$length = 5;
echo "Test with $length : ".getShippingTotal($length)." <br />";
function getShippingTotal($length) {
$shipping2=280;
$shipping3=680;
$total = 0;
for($i=0; $i < $length; $i++) {
if($i == 0) {
$total += $shipping2+$shipping3;
} else {
$total += $shipping2;
}
}
return $total;
}
I have tested it and it gave me:
Test with 1 : 960
Test with 2 : 1240
Test with 3 : 1520
Test with 4 : 1800
Test with 5 : 2080

How to reliably find similar strings to that typed in

I have an interface where a user will enter the name of a company. It then compares what they typed to current entries in the database, and if something similar is found it presents them with options (in case they misspelled) or they can click a button which confirms what they typed is definitely new and unique.
The problem I am having is that it is not very accurate and often brings up dozens of "similar" matches that aren't that similar at all!
Here is what I have now, the first large function I didn't make and I am not clear on what exactly it does. Is there are much simpler way to acheive what I want?
// Compares strings and determines how similar they are based on a nth letter split comparison.
function cmp_by_optionNumber($b, $a) {
if ($a["score"] == $b["score"]) return 0;
if ($a["score"] > $b["score"]) return 1;
return -1;
}
function string_compare($str_a, $str_b)
{
$length = strlen($str_a);
$length_b = strlen($str_b);
$i = 0;
$segmentcount = 0;
$segmentsinfo = array();
$segment = '';
while ($i < $length)
{
$char = substr($str_a, $i, 1);
if (strpos($str_b, $char) !== FALSE)
{
$segment = $segment.$char;
if (strpos($str_b, $segment) !== FALSE)
{
$segmentpos_a = $i - strlen($segment) + 1;
$segmentpos_b = strpos($str_b, $segment);
$positiondiff = abs($segmentpos_a - $segmentpos_b);
$posfactor = ($length - $positiondiff) / $length_b; // <-- ?
$lengthfactor = strlen($segment)/$length;
$segmentsinfo[$segmentcount] = array( 'segment' => $segment, 'score' => ($posfactor * $lengthfactor));
}
else
{
$segment = '';
$i--;
$segmentcount++;
}
}
else
{
$segment = '';
$segmentcount++;
}
$i++;
}
// PHP 5.3 lambda in array_map
$totalscore = array_sum(array_map(function($v) { return $v['score']; }, $segmentsinfo));
return $totalscore;
}
$q = $_POST['stringA'] ;
$qLengthMin = strlen($q) - 5 ; // Part of search calibration. Smaller number = stricter.
$qLengthMax = strlen($q) + 2 ; // not in use.
$main = array() ;
include("pdoconnect.php") ;
$result = $dbh->query("SELECT id, name FROM entity_details WHERE
name LIKE '{$q[0]}%'
AND CHAR_LENGTH(name) >= '$qLengthMin'
#LIMIT 50") ; // The first letter MUST be correct. This assumption makes checker faster and reduces irrelivant results.
$x = 0 ;
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
$percent = string_compare(strtolower($q), strtolower(rawurldecode($row['name']))) ;
if($percent == 1) {
//echo 1 ;// 1 signifies an exact match on a company already in our DB.
echo $row['id'] ;
exit() ;
}
elseif($percent >= 0.6) { // Part of search calibration. Higher deci number = stricter.
$x++ ;
$main[$x]['name'] = rawurldecode($row['name']) ;
$main[$x]['score'] = round($percent, 2) * 100;
//array_push($overs, urldecode($row['name']) . " ($percent)<br />") ;
}
}
usort($main, "cmp_by_optionNumber") ;
$z = 0 ;
echo '<div style="overflow-y:scroll;height:175px;width:460px;">' ;
foreach($main as $c) {
if($c['score'] > 100) $c['score'] = 100 ;
if(count($main) > 1) {
echo '<div id="anysuggested' . $z . '" class="hoverdiv" onclick="selectAuto(' . "'score$z'" . ');">' ;
}
else echo '<div id="anysuggested' . $z . '" class="hoverdiv" style="color:#009444;" onclick="selectAuto(' . "'score$z'" . ');">' ;
echo '<span id="autoscore' . $z . '">' . $c['name'] . '</span></div>' ;
$z++ ;
}
echo '</div>' ;
Comparing strings is a huge topic and there are many ways to do it. One very common algorithm is called the Levenshtein difference. This is a native implementation in PHP but none in MySQL. There is however an implementation here that you could use.
You need aproximate/fuzzy string matching.
Read more about
http://php.net/manual/en/function.levenshtein.php, http://www.slideshare.net/kyleburton/fuzzy-string-matching
The best way would be to use some index based search engine like SOLR http://lucene.apache.org/solr/.

Categories