-
-
Notifications
You must be signed in to change notification settings - Fork 359
Added intergration of Monte Carlo for PHP #431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added intergration of Monte Carlo for PHP #431
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code runs fine for radius = 1, although it takes quite a while to run with 100 million samples.
$percentError = abs($piEstimate - pi()) / pi() * 100; | ||
echo sprintf('The estimate of PI is: %s', $piEstimate); | ||
echo PHP_EOL; | ||
echo sprintf('The percent error is: %s', $percentError); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing ?> at the end, also should have 1 newline at end of file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?> is discouraged and not needed since PHP 5.3 ( I think that version, not sure if 2/3/4 ).
I haven't left newline in any of previous PHP files, so this is with same style and format
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment about ?> was a mixup where I thought the code wasn't running because it didn't read a closing tag. It actually was running but was very slow.
The newline requirement is a git requirement rather than a php requirement iirc, Github warns that there is no newline at the end of file. I think it's because it messes with deltas of files.
|
||
function in_circle(float $positionX, float $positionY, float $radius = 1): bool | ||
{ | ||
return pow($positionX, 2) + pow($positionY, 2) < pow(abs($radius), 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should just do
$positionX * $positionX + $positionY * $positionY + $positionZ * $positionZ
The abs also seems completley unnecessary since x^2 is always positive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still hasn't been resolved btw.
|
||
function random_zero_to_one(): float | ||
{ | ||
return mt_rand(0, 100) / 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for the 100? The recomended way to get a random float is the same as C:
return mt_rand() / mt_getrandmax();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, there is. We want number in interval <0,1> so I'm getting int in range <0,100> and dividing 100 to get required number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That results in only 101 posible values 0.000, 0.001, 0.002, ..., 0.999, 1.0, running over 101^2 times would then be meaningless, instead you should take advantage of the full range of floating point precision by dividing by mt_getrandmax()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, it's changed, thanks for explanation :)
$in_circle_count = 0; | ||
|
||
for ($i = 0; $i < $samples; $i++) { | ||
if (in_circle(random_zero_to_one(), random_zero_to_one(), $radius)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x and y position need to be multiplied by $radius for proper range of random values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't seen any of the other implementations use radius to multiply X or Y. So what's different in this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other implementations chose for radius to be a constant 1.0, you put radius as a function parameter which default value 1.0
Either you can make radius constant 1.0 or implement it so it correctly calculates pi when the radius parameter is not equal to 1.0
Take a look at the python implementation, they generate random numbers from 0 to radius. The easiest way to do this is just multiply your existing random function by $radius.
|
||
$piEstimate = monte_carlo(100000000); | ||
$percentError = abs($piEstimate - pi()) / pi() * 100; | ||
echo sprintf('The estimate of PI is: %s', $piEstimate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- PHP has a printf function
- Probably should use %f for these values, php converts em anyway but no harm in being more correct.
- Why are we using PHP_EOL rather than \n, it doesn't work for single quote strings but they work fine in double quotes
printf("The estimate of PI is: %f\n", $piEstimate);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- it has, but there is not much difference and sprintf gives easier way to extract variable
- %f would generate X.XXXXX format when %s givex X.XX (depending on number of numbers after dot)
- PHP_EOL is constant depending on environment. from SO "PHP_EOL represents the endline character for the current system", so it's much prefered to use it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, I don't understand what you mean by "sprintf gives easier way to extract variable" but your other arguments make sense, I was under the impression PHP would \n to the correct line ending like C/C++.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's basically from my experience, where you don't print to console, but you need to work with strings, build them, etc. You can store sprintf to variable and work with it later. printf would print to output.
yes, it would but with PHP_EOL. otherwise if you specify \n it uses that, which might be problem on some platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can store sprintf to variable and work with it later.
You do not do that, though, so there's no reason to use it. I have to agree with @Gorzoid here. printf()
makes a little more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I give you this one, I'm gonna change it. But still I'm staying, that sprintf looks better 🤣
For the newline at the end of files, if you have an editor or IDE that supports EditorConfig, it can be added automatically, along with enforcing other style guidelines:
which I'm having a hard time understanding (https://stackoverflow.com/questions/1584481/php-line-indentation), so I don't know what they should be. |
@berquist I know it can be set, but there is not any setting for PHP in editorconfig. About the newline. What's the benefit of that in PHP file? |
I was sort of prompting you to add the correct settings to the .editorconfig file, because I don't know what they should be, and you probably do :) See here for why adding a newline may be considered important: https://stackoverflow.com/q/5813311 (again, EditorConfig will do this automatically when the plugin is on). |
1st merge #442 , then I modify code style :) |
Changed random_zero_to_one float calculation
Multiplying X,Y by radius
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have many complaints and they are exclusively related to code style, but they're somewhat important and we should talk about them before we continue adding PHP code to the project.
changed sprintf to printf
changed function parameters to camel_case
@Butt4cak3 so my proposition:
if yes, I write it to the editorconfig PR and modify other PR based on our resulted styled. |
Agreed. |
variable names changed back to camelCase
change $in_circle_count to $inCircleCount
as we talked, this should be ready for final review @Butt4cak3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 2 more things. Don't forget to update the line numbers in the .md file once you added the brackets for the if statement.
$inCircleCount = 0; | ||
|
||
for ($i = 0; $i < $samples; $i++) { | ||
if (in_circle(random_zero_to_one() * $radius, random_zero_to_one() * $radius, $radius)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taken from PSR-2:
The body of each structure MUST be enclosed by braces. This standardizes how
the structures look, and reduces the likelihood of introducing errors as new
lines get added to the body.
|
||
function in_circle(float $positionX, float $positionY, float $radius = 1): bool | ||
{ | ||
return pow($positionX 2) + pow($positionY, 2) < pow($radius, 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing comma between $positionX
and 2
.
No description provided.