My primary question is:
Is this alot of loops?
while ($decimals < 50000 and $remainder != "0") {
$number = floor($remainder/$currentdivider); //Always round down! 10/3 =3, 10/7 = 1
$remainder = $remainder%$currentdivider; // 10%3 =1, 10%1
$thisnumber = $thisnumber . $number;
$remainder = $remainder . 0; //10
$decimals += 1;
}
Or could I fit more into it? -without the server crashing/lagging.
I'm just wondering,
Also is there a more effiecent way of doing the above? (e.g. finidng out that 1/3 = 0.3 to 50,000 decimals.)
Finally:
I'm doing this for a pi formulae the (1 - 1/3 + 1/5 - 1/7 etc.) one,
And i'm wondering if there is a better one. (In php)
I have found one that finds pi to 2000 in 4 seconds.
But thats not what I want. I want an infinite series that converges closer to Pi
so every refresh, users can view it getting closer...
But obv. converging using the above formulae takes ALONG time.
Is there any other 'loop' like Pi formulaes (workable in php) that converge faster?
Thanks alot...
Here you have several formulas for calculating Pi:
http://mathworld.wolfram.com/PiFormulas.html
All of them are "workable" in PHP, like in any other programming language. A different question is how fast they are or how difficult they are to implement.
If the formulas converge faster or slower, it's a Math question, not about programming, so I can't help you. I can tell you that as a rule of a thumb, the less nested loops you put, the faster will be your algorithm (this is a general rule, don't take it as the absolute truth!)
Anyway, since the digits of Pi are known until a certain digit, why don't you copy it into a file and then just index it? That will be extremely fast :)
You can check previous answers to similar questions:
How can pi be calculated to a set number of digits in PHP?
https://stackoverflow.com/questions/3045020/which-is-the-best-formulae-to-find-pi
Check http://mathworld.wolfram.com/PiIterations.html (taken from the last answer). Those formulaes are using iterations and can therefor be implemented using a loop.
You should use google and search for "php implementation xxxxxxx" (where xxxxxx stands for the algorithm name you want to search for).
EDIT: Here is an implementation of Vietas formula using a while-loop in php.
Related
I have a very large number:
char *big_numbr_str = "4325242066733762057192832260226492766115114212292022277";
I want to keep square-rooting this number until it's < 1000. In PHP, I can do this relatively easily:
while($num > 1000):
$num = sqrt($num);
endwhile;
$num = floor($num);
I'm now trying to achieve the same in C, to end with the same result. For reference, after 5 cycles in the while loop, the end result in PHP from the above snippet + starting number is 50; If you square-root this number 5 times anywhere else you should get a similar result, rounded down.
How would I achieve the same in plain C? Seems storing a number of this size is more complex in C than expected.
You'll need a big number library to handle numbers like this. On Linux, you can try GMP.
Alternately, you can write your own bigint routine and implement square root manually. This will take some time to implement properly, as you basically have to do all the math by hand a digit at a time. It can be done (I've done it), but it won't be "simple".
In order to store such a large integer (4325242066733762057192832260226492766115114212292022277) you can use array of integers, store a single digit per element. The array should act like a single integer. Write the routines to do the computation (like the way you would do in a piece of paper).
Alternatively, google bignum c, and see if you can find any library that implements large integer arithmetic. Take a look at bignum.c by Steven Skiena, libraries like MPFR and MPIR.
>=
Why use the above and not just the greater than but with one number less.
For example:
> 8
Is the same as
>= 9
I know it's not a huge deal, but it just seems to serve no purpose to me.
FYI I'm still fairly beginner with PHP so I'm asking a lot of 'why's' at the moment
Let's use an example where you want to cover the left side of the equation being greater than or equal to data input by a user or coming from another variable (something where you don't actually have a hardcoded number).
Your options are $value >= $input or $value > ( $input - 1 )
Very often when writing software, you won't have a specific number in mind. Values change. Writing production software is more about logic than it is math.
How would you represent any number greater or equal to 1? If your logic was true, then $value > 0 would be enough, but if we are dealing with decimals, then 0.95 would be greater than 0 and this 0.95>0 would equate to TRUE while 0.95 >= 1 would equate to false.
You might then follow up your question with "What if we are only using integers and not decimals?". Then in that case mathematically you are correct in assuming that the logic would be the same in most situations (I say most because to say something is ALWAYS true in programming is a dangerous statement to make).
However, in practical terms, >= is more visual and clear to most, and if for some reason you had to change your code in the future to take decimals into account, your site would have a costly error.
I've been testing the randomness of generated values in PHP, and have been considering 32bit hexadecimal to represent a unique state within a given time frame.
I wrote this simple test script:
$checks = [];
$i = 0;
while (true) {
$hash = hash('crc32b', openssl_random_pseudo_bytes(4));
echo $hash . PHP_EOL;
if (in_array($hash, $checks)) {
echo 'Copy: ' . $i . PHP_EOL;
break;
}
$i++;
$checks[] = $hash;
}
Surprisingly (to me) this script generates a copy in less than 100,000 iterations, and as low as 1000 iterations.
My question is, am I doing something wrong here? Out of 4 billion possibilities, this level of frequency seems too unlikely.
No, this is not surprising, and there is nothing wrong with the random number generator. This is the birthday problem. With just 23 people in a room, the probability that two of them have the same birthday is 50%. This is perhaps counter-intuitive until you realize that there are 253 possible pairings of 23 people, so you get 253 shots at two people having the same birthday.
You are doing the same thing here. You are not looking to see when you hit a particular 32-bit value. Instead you are looking for a match between any two values you have created so far, which gives you a lot more chances. If you consider step 100,000, you have a 1 in 43,000 chance of matching one of the numbers you have created so far, as opposed to a 1 in 4,300,000,000 chance of matching a particular number. In the run up to 100,000, you have added up a lot of those chances.
See this answer here on stackoverflow for the calculation for a 32-bit value. On average you only need about 93,000 values to get a hit.
By the way, the use of a CRC-32 on the four-byte random value has no bearing here. The result would be the same with or without it. All you're doing is mapping each 32-bit number uniquely (one-to-one and onto) to another 32-bit number.
I'm looking to find an algorithm that I can implement in PHP to get the natural log() of an integer number using arbitrary precision maths. I'm limited by the PHP overlay library of the GMP library (see http://php.net/manual/en/ref.gmp.php for available GMP functions in PHP.)
If you know of a generic algorithm that can be translated into PHP, that would also be a useful starting point.
PHP supports a native log() function, I know, but I want to be able to work this out using arbitrary precision.
Closely related is getting an exp() function. If my schoolboy Maths serves me right, getting one can lead to the other.
Well you would have the Taylor series, that can be rewritten for better convergence
To transform this nice equality into an algorithm, you have to understand how a converging series work : each term is smaller and smaller. This decrease happens fast enough so that the total sum is a finite value : ln(y).
Because of nice properties of the real numbers, you may consider the sequence converging to ln(y) :
L(1) = 2/1 * (y-1)/(y+1)
L(2) = 2/1 * (y-1)/(y+1) + 2/3 * ( (y-1)/(y+1) )^3
L(3) = 2/1 * (y-1)/(y+1) + 2/3 * ( (y-1)/(y+1) )^3 + 2/5 * ( (y-1)/(y+1) )^5
.. and so on.
Obviously, the algorithm to compute this sequence is easy :
x = (y-1)/(y+1);
z = x * x;
L = 0;
k = 0;
for(k=1; x > epsilon; k+=2)
{
L += 2 * x / k;
x *= z;
}
At some point, your x will become so small that it will not contribute to the interesting digits of L anymore, instead only modifying the much smaller digits. When these modifications start to be too insignificant for your purposes, you may stop.
Thus if you want to achieve a precision 1e^-20, set epsilon to be reasonably smaller than that, and you're good to go.
Don't forget to factorize within the log if you can. If it's a perfect square for example, ln(a²) = 2 ln(a)
Indeed, the series will converge faster when (y-1)/(y+1) is smaller, thus when y is smaller (or rather, closer to 1, but that should be equivalent if you're planning on using integers).
Is it possible to generate this kind of random curves?
I've tried IMagick bezier curves (see http://www.php.net/manual/en/function.imagickdraw-bezier.php), but even with 20-30 points they do not look like this. Here is my sample http://mechanicalzilla.com/sandbox/imagick/curve.php
Thank you.
I bet you could write an algorithm which would basically take x number of random twists before going straight to the exit coordinates. This also assumes that algorithm is smart enough to check the angle of the turn. (assuming you don't want to endup in knot-web)
However, assuming that this isn't your graduation task or that you are paid on per-hour basis to work on this, this would be a waste of time and success is highly doubtful.
Even if you'd manage to generate single line algorithm, doing it so that the lines wouldn't come too close to each other is close to impossible. You will end up with something like this:
Looks like:
x = 0; y = 0; angel = 0;
while (true) {
angel = angel + 0.5 - random(1);
x1 = x + 0.1 * cos(angel);
y1 = y + 0.1 * sin(angel);
if (abs(x1 - x) + abs(y1 - y) < 10)
drawline(x,y,x1,y1);
x = x1; y = y1;
if (x < 0) x = width;
if (y < 0) y = height;
if (x > width) x = 0;
if (y > height) y = 0;
}
This is far from a complete answer, but in my mind's eye seems like it could help you:
Instead of drawing curves from the start to the end point of the entire line, consider subdividing your board into a evenly spaced grid. Each square of one column of the grid is entitled to have one point of one curve in it, and you'd steadily advance from left to right (at first? for simplicity's sake.).
The randomness would come into play by picking a square for a curve - to prevent it from getting too chaotic, you could give this randomness bounds, say, "you're not allowed to pick a square that (if a distance from square to square is considered 1) violates abs(current vertical position - new vertical position) <= 5 unless none such is free anymore at this point" or some other arbitrary restraint. ("unless none such is free anymore at this point" is important, otherwise it's possible to lock yourself into an unsolvable state.)
(Sorry, drawing curves with my mouse -> worst/no interpolation ever. Catmull-Rom interpolation will probably be your friend here, though, I imagine.)
The display should be loose enough given that your curve points cannot arbitrarily scatter together given a grid, but it's probably very difficult to get the curve to connect to the end point 'fluidly' - might be a good solution if you don't mind arbitrary end points, though, read as, the algorithm can decide for itself where it wants the line to end.
Think this idea might help you with your curves?
One way to approach this would be to first generate a set of random curves and then use a physics solver to apply repulsion forces between them to avoid clumping.
Here's a quick proof of concept:
I created this using a very niche tool (for anyone interested: Kangaroo Physics solver, a plugin for Grasshopper, visual scripting language for Rhinoceros3d) but you can probably recreate the same concept in any mainstream programming language, eg. Python.