Compare two charts and get percentage of similarity - php

question:How to compare two chart ranges, and get percentage as a result.
I want to compare two chart parts, (range of 60 values), and as a result get percentage of difference. So i can find very similar chart curves.
(Example:Get all charts that are 90% similar to this one)
For every range, data is stored in 60 number array.
Every range starts with 0 and all next numbers represent chart value from that moment.("+" chart goes up and "-" chart goes down)
$range1 = array(0.00,-0.90,2.10,0.10,-3.40,-4.30,-1.90,-0.30,0.00,0.10,-0.60,-0.20,-0.30,-0.30,1.00,-0.90,-0.50,1.00,2.80,5.00,5.50,5.20,6.70,5.50,5.70,7.30,6.00,5.10,5.30,11.10,10.90,9.00,7.10,6.60,7.00,5.50,5.50,12.60,15.60,14.30,18.50,16.60,16.60,20.30,20.60,18.10,16.10,19.10,14.40,18.70,17.40,17.80,17.20,19.90,20.60,17.70,17.00,17.50,16.70,14.70);
$range2 = array(0.00,-2.90,-3.60,-3.10,-3.90,-5.90,-11.80,-8.40,-8.00,-8.40,-8.20,-7.00,-7.60,-7.30,-5.10,-7.20,-7.30,-7.40,-7.70,-8.90,-9.30,-9.30,-9.90,-7.50,-11.70,-12.20,-19.80,-19.60,-19.90,-19.00,-22.10,-19.10,-20.10,-18.90,-19.70,-19.90,-16.50,-23.70,-26.60,-24.20,-28.30,-27.00,-28.60,-28.90,-22.90,-24.00,-25.10,-24.30,-18.40,-31.70,-29.80,-29.00,-29.50,-28.30,-35.50,-27.60,-34.00,-32.80,-36.00,-34.40,);
$result = some_specific_manual_written_function($range1, $range2);
//as a result i want get percentage or something else from what i can how similar charts are
I will do it reading csv files and then storing it to db, so it can be done with php or python.

Try this
function some_specific_manual_written_function($range1, $range2)
{
$match = 0;
for($i=0; count($range1); $i++)
{
if(in_array($range[$i],$range2))
{
$match++;
}
}
$percentage_match = (count($range1)/$match ) * 100;
echo "Perncetage Match is : ".$percentage_match."%";
return $percentage_match;
}

function similiar($range1, $range2) {
$i = 0;
foreach ($range1 as $k => $v) {
if ($range2[$k] == $v) {
$i++;
}
}
$return ($i/count($range1))*100);
}

Related

How to sum array value and save in list

I have file of more than 7mb which has numbers which I put in and array below:
$allbarcodes = array(3117148100,3117148110,3117148120,3117148130,3118011010,3118011020,3118011060,3118011070,3118011080,3118011090,3118011100,3118011110,3118011120,3118011130,3118012010,3118012020,3118012060,3118012070,3118012080,3118012090,3118012100,3118012110,3118012120,3118012130,3118654010,3118654020,3118654060,3118654070,3118654080,3118654090,3118654100,3118654110,3118654120,3118654130,3118797010,3118797020,3118797060,3118797070,3118797080,3118797090,3118797100,3118797110,3118797120,3118797130,3118846010,3118846020,3118846060,3118846070,3118846080,3118846090,3118846100,3118846110,3118846120,3118846130,3119009010,3119009020,3119009060,3119009070,3119009080,3119009090,3119009100,3119009110,3119009120,3119009130,3119011010,3119011020,3119011060,3119011070,3119011080,3119011090,3119011100,3119011110,3119011120,3119011130,3119012010,3119012020,3119012060,3119012070);
for($i = 1; $i < count($allbarcodes); $i++)
{
try
{
$sumOfnum = summation((int)$allbarcodes[$i]);
$allbarcodes[$i] = str_pad($allbarcodes[$i],10,'0',STR_PAD_LEFT);
array_push($barcodeList,$sumOfnum.",".$allbarcodes[$i]);
}
catch(Exception $e)
{
echo "n Exception Caught", $e->getMessage();
}
}
function summation( $n)
{
$m =0; $sum=0;
while($n != 0)
{
$m = $n % 10;
$sum = $sum + $m;
$n = (int)$n/10;
}
return $sum;
}
I have about 300,000 numbers in a file and I need to sum all digits and create a file of sum value and save all numbers of that sum value in txt file. I have written below statement to create array:
array_push($barcodeList,$sumOfnum.",".(int)$allbarcodes[$i]);
For example: if number is "2399879110" its sum is "49" and this number should be written in 49.txt file.
For some numbers this code is working fine, but when numbers are more then this code not working properly and all numbers or various sum values like 23,35 or whatever started copying in 46.txt file.
On 64 bit systems integers can be from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
On 32 bit systems integers can be from -2,147,483,648 to 2,147,483,647
Your numbers seem to be greater than the 32 bit maximum, however, if you are reading them from a file they should come as strings, so don't cast them to (int). Also, it's quite a bit easier:
foreach($allbarcodes as $num) {
$result[] = array_sum(str_split($num));
}
Demo with output on 64 bit system.
As it looks like you want sum,number:
$result[] = array_sum(str_split($num)).",$num";
As for saving the number in a file named as the sum:
foreach($allbarcodes as $num) {
file_put_contents("/path/to/".array_sum(str_split($num).".txt", $num);
}
If you want to write sum,number in the file then of course:
$sum = array_sum(str_split($num);
file_put_contents("/path/to/$sum.txt", "$sum,$num");

Updating spline class on a graph so that the highest peak is the marker position - JPGraph

I have created a graph using Jpgraph (http://www.jpgraph.com).
Jpgraph has a spline class which smooths out the lines on the line graph. However it does not work as I expected. As you can see, the highest peak of the line goes above the actual markings (the red squares). Friday 10pm is 2.0 however it appears to be higher than that around 6am friday.
A poorly laptop touchpad drawn example of what I would have expected is below :)
I have managed to track down the class to jpgraph_regstat.php. Any idea how to make the center of the peak the actual markings?
//------------------------------------------------------------------------
// CLASS Spline
// Create a new data array from an existing data array but with more points.
// The new points are interpolated using a cubic spline algorithm
//------------------------------------------------------------------------
class Spline {
// 3:rd degree polynom approximation
private $xdata,$ydata; // Data vectors
private $y2; // 2:nd derivate of ydata
private $n=0;
function __construct($xdata,$ydata) {
$this->y2 = array();
$this->xdata = $xdata;
$this->ydata = $ydata;
$n = count($ydata);
$this->n = $n;
if( $this->n !== count($xdata) ) {
JpGraphError::RaiseL(19001);
//('Spline: Number of X and Y coordinates must be the same');
}
// Natural spline 2:derivate == 0 at endpoints
$this->y2[0] = 0.0;
$this->y2[$n-1] = 0.0;
$delta[0] = 0.0;
// Calculate 2:nd derivate
for($i=1; $i < $n-1; ++$i) {
$d = ($xdata[$i+1]-$xdata[$i-1]);
if( $d == 0 ) {
JpGraphError::RaiseL(19002);
//('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
}
$s = ($xdata[$i]-$xdata[$i-1])/$d;
$p = $s*$this->y2[$i-1]+2.0;
$this->y2[$i] = ($s-1.0)/$p;
$delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) -
($ydata[$i]-$ydata[$i-1])/($xdata[$i]-$xdata[$i-1]);
$delta[$i] = (6.0*$delta[$i]/($xdata[$i+1]-$xdata[$i-1])-$s*$delta[$i-1])/$p;
}
// Backward substitution
for( $j=$n-2; $j >= 0; --$j ) {
$this->y2[$j] = $this->y2[$j]*$this->y2[$j+1] + $delta[$j];
}
}
// Return the two new data vectors
function Get($num=50) {
$n = $this->n ;
$step = ($this->xdata[$n-1]-$this->xdata[0]) / ($num-1);
$xnew=array();
$ynew=array();
$xnew[0] = $this->xdata[0];
$ynew[0] = $this->ydata[0];
for( $j=1; $j < $num; ++$j ) {
$xnew[$j] = $xnew[0]+$j*$step;
$ynew[$j] = $this->Interpolate($xnew[$j]);
}
return array($xnew,$ynew);
}
// Return a single interpolated Y-value from an x value
function Interpolate($xpoint) {
$max = $this->n-1;
$min = 0;
// Binary search to find interval
while( $max-$min > 1 ) {
$k = ($max+$min) / 2;
if( $this->xdata[$k] > $xpoint )
$max=$k;
else
$min=$k;
}
// Each interval is interpolated by a 3:degree polynom function
$h = $this->xdata[$max]-$this->xdata[$min];
if( $h == 0 ) {
JpGraphError::RaiseL(19002);
//('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
}
$a = ($this->xdata[$max]-$xpoint)/$h;
$b = ($xpoint-$this->xdata[$min])/$h;
return $a*$this->ydata[$min]+$b*$this->ydata[$max]+
(($a*$a*$a-$a)*$this->y2[$min]+($b*$b*$b-$b)*$this->y2[$max])*($h*$h)/6.0;
}
}
Code example using spline can be found here (http://jpgraph.net/download/manuals/chunkhtml/example_src/splineex1.html)
If you really want to use a spline to interpolate your data values, and you want to minimize deviations above and below your actual samples (data points), then you're going to need more samples. You could get them by generating fake/artificial data points via linear interpolation between samples and then regenerating the spline (in which case you'll end up with something more like your touchpad drawing). But if you're trying to generate a "smooth" graph which minimizes some sort of average deviation from reality, then you may need to use something other than a spline.

Find the matched value of an array with a given value

I have an array of value series like:
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
Another value getting from DB like:
$point = $data[‘earned_point’];
I need the highest match from the series. such as I got a value from db (1500) the highest match of the value is 1000 in the series, so I need to get the $series[4] and make it
$reward = $series[4] * 0.1;
I'll run it in a loop to do it for all the values got from DB.
I'm posting alternate code as the accepted answer while is correct can be very inefficient if you are working with a large array.
<?php
function computeReward($series, $point, $percent = 0.1){
arsort($series); // sort the series in reverse so we can pass any array and the highest number will be the first because we are looking for a number lower or equal to our point
foreach($series as $min_point){
if($min_point <= $point){
return $min_point * $percent; // return the min_point * the percentage, this stops the loop there for being more efficient
}
}
}
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
$point = $data['earned_point'];
$reward = computeReward($series, $point);
?>
Do you mean you want to get which highest $series item is equal or less than $point ?
<?php
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
$point = $data['earned_point'];
foreach ($series as $min_point) {
if ($point >= $min_point) {
$matched_min_point = $min_point;
}
}
$reward = $matched_min_point*0.1;
Let me know if this works for you

Random Numbers, Column and Row. PHP

Please excuse me as this is my first post and I am fairly new to any type of programming. I hope my question is clear, I am using Excel references as I think this explains what I am trying to do best.
I am trying to generate random numbers for a pool. I have 8 rows of numbers and each row contains 10 spots, 0 to 9. I want to have a random number in each row and make sure the the number does not repeat in each row.
Example Grid - 8 columns wide x 10 rows long.
I am repeating this scrip for each column, but I am getting the same number is rows and I want make sure that does not happen.
for ($i=1; $i<=10; $i++) {
while (1) {
$duplicate = 0;
$num=rand(0,9);
for ($x=1; $x<$i; $x++) {
if ($NFC1[$x]==$num) { $duplicate = 1; }
}
if ($duplicate==0) {
$NFC1[$i]=$num;
break;
}
}
}
This is the results, as you can see I have random numbers is each column but not in each row.
"4";"8";"5";"5";"0";"4";"2";"7"
"5";"9";"4";"3";"9";"9";"9";"0"
"9";"5";"1";"1";"5";"8";"6";"1"
"7";"4";"6";"2";"6";"7";"3";"3"
"2";"6";"8";"4";"7";"2";"7";"5"
"0";"1";"0";"7";"2";"1";"4";"6"
"1";"7";"9";"9";"4";"3";"0";"4"
"3";"0";"3";"0";"3";"5";"5";"9"
"8";"2";"7";"8";"1";"6";"8";"2"
"6";"3";"2";"6";"8";"0";"1";"8"
The answer from here addapted to non-square array may looks like below:
$rows = 10; // Number of rows
$columns = 8; // Number of columns
$row = range(0, $columns-1);
$column = range(0, $rows-1);
shuffle($row);
shuffle($column);
// Create an array
foreach ($row as $x => $value)
foreach ($column as $y)
$array[$y][$x] = $value++ % max($rows, $columns);
And if you want to see the result:
foreach($array as $r) {
foreach($r as $number) {
echo $number.' ';
}
echo "<br/>";
}

serverside clustering google maps markers

I would like to know what is the fastest algorithm for clustering markers in PHP?
Only thing I need from the cluster function is an output with a cluster obj, that has properties: lat,lng and size.
and then the markers that weren't clustered of course, but I can't seem to find php code for this, and there must be some?
I'm looking for the code-behind that would produce this kind of result? (Or perhaps perform better). http://maps.forum.nu/server_side_clusterer/
So far I've tried with:
function ClusterMarkers($markers,$ZOOM)
{
$this->load->library('firephp');
$singleMarkers = array();
$clusterMarkers = array();
// Minimum distance between markers to be included in a cluster, at diff. zoom levels
$DISTANCE = (10000000 >> $ZOOM);
// Loop until all markers have been compared.
while (count($markers)) {
$marker = array_pop($markers);
$cluster = array();
// Compare against all markers which are left.
foreach ($markers as $key => $target) {
$pixels = abs($marker['lat']-$target['lat']) + abs($marker['lng']-$target['lng']);
$this->firephp->log('pix :'.$pixels);
if ($pixels < $DISTANCE) {
unset($markers[$key]);
$cluster[] = $target;
}
}
// If a marker has been added to cluster, add also the one we were comparing to.
if (count($cluster) > 0) {
$cluster[] = $marker;
$clusterMarkers[] = $cluster;
} else {
$singleMarkers[] = $marker;
}
}
return array('singlemarkers' => $singleMarkers, 'clustermarkers' => $clusterMarkers);
}
My data is then jsonized, but the clustermarkers array contains all the markerdata, and I'm wondering how I would effectively simply set a lat,lng and a size without having to recalculate to resourcedemanding everytime a new marker is added.
Basically the $clusterMarkers array is a group of clustered markers, so you could simply take the centroid of the containing markers instead of returning all markers. Before returning the result, do:
foreach($clusterMarkers as $key => $cluster) {
$centroid = array('lat' => 0, 'lng' => 0, 'count' => 0);
foreach($cluster as $marker) {
$centroid['lat'] += $marker['lat']; // Sum up the Lats
$centroid['lng'] += $marker['lng']; // Sum up the Lngs
$centroid['count']++;
}
$centroid['lat'] /= $centroid['count']; // Average Lat
$centroid['lng'] /= $centroid['count']; // Average Lng
$clusterMarkers[$key] = $centroid; // Overwrite the cluster with the single point.
}
I use the MarkerClusterer JavaScript class from Xiaoxi Wu.
You may want to take a look and adapt it to PHP:
http://googlegeodevelopers.blogspot.com/2009/04/markerclusterer-solution-to-too-many.html

Categories