Let's say we have a code:
<?php
$maximum = 10000;
$minimum = 5000;
$size = 10000;
$step = 0.0001;
$total = 0;
$counter = $maximum;
while($counter >= $minimum)
{
$counter -= $step;
$total += $size / $maximum * $step / $counter;
}
echo "Total is: $total\n";
?>
How to express $total variable as a formula? The code acts as an integral where step is infinitesimally small.
Your integral is:
$total = integral(x from $minimum to $maximum; $size / $maximum / x);
$size / $maximum is constant and thus simply scales the integral. The closed form of the integral is therefore:
$total = $size / $maximum * (log($maximum) - log($minimum))
= $size / $maximum * log($maximum / $minimum)
Assuming that both $maximum and $minimum are positive.
Related
Does anyone know how to convert a Hex color to HSL in PHP? I've searched but the functions that I’ve found don’t convert precisely the color.
I think the mistake in the second answer is using integer division rather than fmod() when calculating the hue when red is the maximum colour value $hue = (($green - $blue) / $delta) % 6;
I think the mistake in the first answer is in the saturation calculation -
for me $s = $l > 0.5 ? $diff / (2 - $max - $min) : $diff / ($max + $min); is a bit confusing to unpick
Since usually when I want to convert RGB to HSL I want to adjust the lightness value to make a lighter or darker version of the same colour, I have built that into the function below by adding an optional $ladj percent value.
The $hex parameter can be either a hex string (with or without the '#') or an array of RGB values (between 0 and 255)
The return value is an HSL string ready to drop straight in to a CSS colour. ie the values are from 0 to 359 for hue and 0 to 100% for saturation and lightness.
I think this works correctly (based on https://gist.github.com/brandonheyer/5254516)
function hex2hsl($RGB, $ladj = 0) {
//have we got an RGB array or a string of hex RGB values (assume it is valid!)
if (!is_array($RGB)) {
$hexstr = ltrim($RGB, '#');
if (strlen($hexstr) == 3) {
$hexstr = $hexstr[0] . $hexstr[0] . $hexstr[1] . $hexstr[1] . $hexstr[2] . $hexstr[2];
}
$R = hexdec($hexstr[0] . $hexstr[1]);
$G = hexdec($hexstr[2] . $hexstr[3]);
$B = hexdec($hexstr[4] . $hexstr[5]);
$RGB = array($R,$G,$B);
}
// scale the RGB values to 0 to 1 (percentages)
$r = $RGB[0]/255;
$g = $RGB[1]/255;
$b = $RGB[2]/255;
$max = max( $r, $g, $b );
$min = min( $r, $g, $b );
// lightness calculation. 0 to 1 value, scale to 0 to 100% at end
$l = ( $max + $min ) / 2;
// saturation calculation. Also 0 to 1, scale to percent at end.
$d = $max - $min;
if( $d == 0 ){
// achromatic (grey) so hue and saturation both zero
$h = $s = 0;
} else {
$s = $d / ( 1 - abs( (2 * $l) - 1 ) );
// hue (if not grey) This is being calculated directly in degrees (0 to 360)
switch( $max ){
case $r:
$h = 60 * fmod( ( ( $g - $b ) / $d ), 6 );
if ($b > $g) { //will have given a negative value for $h
$h += 360;
}
break;
case $g:
$h = 60 * ( ( $b - $r ) / $d + 2 );
break;
case $b:
$h = 60 * ( ( $r - $g ) / $d + 4 );
break;
} //end switch
} //end else
// make any lightness adjustment required
if ($ladj > 0) {
$l += (1 - $l) * $ladj/100;
} elseif ($ladj < 0) {
$l += $l * $ladj/100;
}
//put the values in an array and scale the saturation and lightness to be percentages
$hsl = array( round( $h), round( $s*100), round( $l*100) );
//we could return that, but lets build a CSS compatible string and return that instead
$hslstr = 'hsl('.$hsl[0].','.$hsl[1].'%,'.$hsl[2].'%)';
return $hslstr;
}
In real life I would break out the hex string to RGB array conversion and the percentage adjustment into separate functions, but have included them here for completeness.
You could also use the percent adjustment to shift the hue or saturation once you've got the colour in HSL format.
function hexToHsl($hex) {
$hex = array($hex[0].$hex[1], $hex[2].$hex[3], $hex[4].$hex[5]);
$rgb = array_map(function($part) {
return hexdec($part) / 255;
}, $hex);
$max = max($rgb);
$min = min($rgb);
$l = ($max + $min) / 2;
if ($max == $min) {
$h = $s = 0;
} else {
$diff = $max - $min;
$s = $l > 0.5 ? $diff / (2 - $max - $min) : $diff / ($max + $min);
switch($max) {
case $rgb[0]:
$h = ($rgb[1] - $rgb[2]) / $diff + ($rgb[1] < $rgb[2] ? 6 : 0);
break;
case $rgb[1]:
$h = ($rgb[2] - $rgb[0]) / $diff + 2;
break;
case $rgb[2]:
$h = ($rgb[0] - $rgb[1]) / $diff + 4;
break;
}
$h /= 6;
}
return array($h, $s, $l);
}
Rewritten (and adjusted a bit) from javascript from https://css-tricks.com/converting-color-spaces-in-javascript/
<?php
function hexToHsl($hex)
{
$red = hexdec(substr($hex, 0, 2)) / 255;
$green = hexdec(substr($hex, 2, 2)) / 255;
$blue = hexdec(substr($hex, 4, 2)) / 255;
$cmin = min($red, $green, $blue);
$cmax = max($red, $green, $blue);
$delta = $cmax - $cmin;
if ($delta === 0) {
$hue = 0;
} elseif ($cmax === $red) {
$hue = (($green - $blue) / $delta) % 6;
} elseif ($cmax === $green) {
$hue = ($blue - $red) / $delta + 2;
} else {
$hue = ($red - $green) / $delta + 4;
}
$hue = round($hue * 60);
if ($hue < 0) {
$hue += 360;
}
$lightness = (($cmax + $cmin) / 2) * 100;
$saturation = $delta === 0 ? 0 : ($delta / (1 - abs(2 * $lightness - 1))) * 100;
if ($saturation < 0) {
$saturation += 100;
}
$lightness = round($lightness);
$saturation = round($saturation);
return "hsl(${hue}, ${saturation}%, ${lightness}%)";
}
Example:
<?php
echo hexToHsl('fbffe0'); // outputs 'hsl(68, 100%, 94%)'
I am building a feedback system: positive, neutral and nagative, I want to get the positive percentage somehow.
$positive = 4;
$neutral = 1;
$negative = 1
So I am trying to get something like 50%. I have tried
$positive / $neutral + $negative;
$positive / $neutral + $negative * 10;
None seem to get the right value.
This should work for you:
<?php
$positive = 4;
$neutral = 1;
$negative = 1;
$total = $positive + $neutral + $negative;
$percentage = ($positive - $negative) / $total * 100;
echo sprintf("%02.2f%%", $percentage);
?>
Output:
50.00%
EDIT:
If you want to count $neutral to positive feedback use this:
$total = $positive + $neutral + $negative;
$percentage = ($positive + $neutral - $negative) / $total * 100;
echo sprintf("%02.2f%%", $percentage);
How do I set the value for an array with division in specific number and the remaining of number will be loopback.
<?php
$total = 125;
$divide = 15;
for($a=0; $a<=$divide; $a++)
{
$b[] = .....; // $total/$divide
}
print_r($b);
?>
The Ouput :
array([0]=>9[1]=>9[2]=>9[3]=>9[4]=>9[5]=>8[6]=>8[7]=>8..[14]=>8)
For example,
$total = 125;
$size = 15;
$chunk = floor($total / $size);
$mod = $total % $size;
if($mod)
$result = array_fill(0, $mod, $chunk + 1) +
array_fill($mod, $size - $mod, $chunk);
else
$result = array_fill(0, $size, $chunk);
I'm using the XIRR function from the php financial library (http://www.phpclasses.org/package/892-PHP-Financial-functions-with-the-Excel-function-names-.html) but I get strange results with these values (dates are d/m/y):
(01/01/2014, -400) , (01/10/2014, 18)
MS Excel correctly returns 0.98, while the XIRR function returns -1.5714653207915E+40. The code is as follow:
$f->XIRR(array(-400,18), array(
mktime(0,0,0,1,1,2014),
mktime(0,0,0,10,1,2014),
), 0.1);
Can anyone explain me what am I doing wrong? Thanks in advance for any help.
I have written one code from PHP Excel Functions.
I have calculated XIRR and XNPV.
Here is code sample with some dummy data.
Main advantage is that, There is no dependency on any library in this
code.
<?php
$rate = 0.12;
$values = array(-5000,-3000,-8000,25000,-4000);
$dates = array('01-02-2015','05-05-2016','02-03-2018','03-03-2019','05-03-2019');
/** FINANCIAL_MAX_ITERATIONS */
define('FINANCIAL_MAX_ITERATIONS', 128);
/** FINANCIAL_PRECISION */
define('FINANCIAL_PRECISION', 1.0e-08);
$result = XIRR($values,$dates,0.1);
print_r($result);
function XIRR($values, $dates, $guess = 0.1) {
$x1 = 0.0;
$x2 = $guess;
$f1 = XNPV($x1, $values, $dates);
$f2 = XNPV($x2, $values, $dates);
for ($i = 0; $i < 128; ++$i) {
if (($f1 * $f2) < 0.0) break;
if (abs($f1) < abs($f2)) {
$f1 = XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates);
} else {
$f2 = XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates);
}
}
$f = XNPV($x1, $values, $dates);
if ($f < 0.0) {
$rtb = $x1;
$dx = $x2 - $x1;
} else {
$rtb = $x2;
$dx = $x1 - $x2;
}
for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) {
$dx *= 0.5;
$x_mid = $rtb + $dx;
$f_mid = XNPV($x_mid, $values, $dates);
if ($f_mid <= 0.0) $rtb = $x_mid;
if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid;
}
}
function XNPV($rate, $values, $dates) {
$valCount = count($values);
$xnpv = 0.0;
for ($i = 0; $i < $valCount; ++$i)
{
$datediff = strtotime($dates[$i]) - strtotime($dates[0]);
$datediff = round($datediff / (60 * 60 * 24));
$xnpv += $values[$i] / pow(1 + $rate,$datediff / 365);
}
return $xnpv;
}
?>
The correct XIRR value is -98.417% as shown below
-400 + 18(1+i)^-(273/365) = 0
18(1+i)^-(273/365) = 400
(1+i)^-(273/365) = 400/18
(1+i)^(273/365) = 18/400
(1+i) = (18/400)^(365/273)
1+i = (0.045)^(1.336996337)
i = (0.045)^(1.336996337) - 1
i = -0.984174769
i = -98.417%
Use the American mm/dd/yyyy :
mktime(0,0,0,1,1,2014),
mktime(0,0,0,1,10,2014)
I am working on a Facebook App that needs to be able to average three numbers. But, it always return 0 as the answer. Here is my code:
$y = 100;
$n = 250;
$m = 300;
$number = ($y + $n + $m / 3);
echo 'Index: '.$number;
It always displays Index: 0
Any ideas?
$y = 100;
$n = 250;
$m = 300;
$number = ($y + $n + $m) / 3;
echo 'Index: '.$number;
Also - you missed ; in the end of the first 3 lines
Your parentheses are grouped wrongly. You should be doing:
$number = ($y + $n + $m) / 3;
Two problems:
You are missing ; at the end of these lines:
$y = 100
$n = 250
$m = 300
And to / has higher precedence than + so you need to do:
$number = ($y + $n + $m) / 3;