Talk:Total circles area: Difference between revisions
(→Link) |
|||
Line 76: | Line 76: | ||
:: Right, I am sorry. In a (Haskell) program types contain lot of information (like telling apart two tuples that contain two doubles). For a second programmer that tries to add more of such information it's easy to miss part of the semantics and introduce wrong type information. I will try to introduce a Angle2 type and fix the code. I am an Haskell newbie myself, but we are learning. --[[User:Bearophile|bearophile]] 19:36, 21 September 2012 (UTC) |
:: Right, I am sorry. In a (Haskell) program types contain lot of information (like telling apart two tuples that contain two doubles). For a second programmer that tries to add more of such information it's easy to miss part of the semantics and introduce wrong type information. I will try to introduce a Angle2 type and fix the code. I am an Haskell newbie myself, but we are learning. --[[User:Bearophile|bearophile]] 19:36, 21 September 2012 (UTC) |
||
:: Done. Please take a look at the code, to make sure I have not used an Angle where instead goes a normal Double, and I have not used an Angle2 where a Vet instead goes. |
:: Done. Please take a look at the code, to make sure I have not used an Angle where instead goes a normal Double, and I have not used an Angle2 where a Vet instead goes. |
||
::: I think it's fine. I changed the polyline area function, maybe it's clearer this way. Also added some comments explaining some odd stuff I did in the code. One thing sort of amuses me is, is there really a need for an <code>Angle</code> type? I mean, it does no harm, but angles are really just plain numbers and doesn't do anything to distinguish itself from a <code>Double</code>. --[[User:Ledrug|Ledrug]] 06:11, 22 September 2012 (UTC) |
|||
==Link== |
==Link== |
Revision as of 06:11, 22 September 2012
Monte Carlo
A semi-important point and semi-nitpicking for doing Monte Carlo: you need to estimate the error in a credible way given the number of samples, and should not output more significant digits than the confidence allows. The current C code sample size of 100M can't possibly allow 8 decimal point precision. --Ledrug 04:29, 16 September 2012 (UTC)
- Right, in the C/Python outputs only the first few digits are correct. Feel free to add a bit of error estimation code.
- This is basically what I used on reddit, but I don't feel like changing the example on the task page because MC really isn't the right tool for this task.
- <lang c>#include <stdio.h>
- include <stdlib.h>
- include <tgmath.h>
- include <time.h>
typedef float flt; flt data[][3] = { { 1.6417233788, 1.6121789534, 0.0848270516}, ... };
- define N sizeof(data)/sizeof(data[0])
int main(void) { flt x0 = 1/0., x1 = -1/0., y0 = 1/0., y1 = -1/0.;
inline flt min(flt x, flt y) { return x < y ? x : y; } inline flt max(flt x, flt y) { return x > y ? x : y; } inline flt sq(flt x) { return x * x; } inline flt rndf(flt x, flt d) { return x + d * rand() / RAND_MAX; }
inline int covered(flt x, flt y) { for (int i = 0; i < N; i++) if (sq(x - data[i][0]) + sq(y - data[i][1]) < data[i][2]) return 1; return 0; }
for (int i = 0; i < N; i++) { flt *p = data[i]; x0 = min(x0, p[0] - p[2]); x1 = max(x1, p[0] + p[2]); y0 = min(y0, p[1] - p[2]); y1 = max(y1, p[1] + p[2]);
p[2] *= p[2]; }
x1 -= x0, y1 -= y0;
flt total = x1 * y1; unsigned long to_try = 0x10000, tries = 0, hit = 0; srand(time(0));
while (1) { hit += covered(rndf(x0, x1), rndf(y0, y1));
if (++tries == to_try) { flt area = total * hit / tries; flt r = (flt) hit / tries; flt s = area * sqrt(r * (1 - r) / tries); printf("%.4f +/- %.4f (%lu samples)\n", area, s, tries); // stop at 3 sigmas if (s * 3 <= 1e-3) break; to_try *= 2; } } return 0; }</lang> --Ledrug 22:09, 16 September 2012 (UTC)
- A bad solution algorithm is quite useful for didactic purposes (but I don't know how much Rosettacode cares for didactic).
Haskell analytical solution
I like the analytical solution in Haskell, but I think a tuples soup harms readability. So do you mind if I replace it with this code that introduces the Vec, Circle and Arc types? http://ideone.com/JjD4x bearophile 12:11, 21 September 2012 (UTC)
- Go ahead. I'm a complete newbie in Haskell, and have no problem with people improving it. --Ledrug 15:04, 21 September 2012 (UTC)
- Actually there is one thing that's not quite right: in an arc ((x,y,r), (a0,a1)) the (a0,a1) is not a vector, they are a pair of angles of the start and end points on the original circle. It doesn't hurt the computation, but as readability goes, nameing them "Vec" is misleading. --Ledrug 18:26, 21 September 2012 (UTC)
- Right, I am sorry. In a (Haskell) program types contain lot of information (like telling apart two tuples that contain two doubles). For a second programmer that tries to add more of such information it's easy to miss part of the semantics and introduce wrong type information. I will try to introduce a Angle2 type and fix the code. I am an Haskell newbie myself, but we are learning. --bearophile 19:36, 21 September 2012 (UTC)
- Done. Please take a look at the code, to make sure I have not used an Angle where instead goes a normal Double, and I have not used an Angle2 where a Vet instead goes.
- I think it's fine. I changed the polyline area function, maybe it's clearer this way. Also added some comments explaining some odd stuff I did in the code. One thing sort of amuses me is, is there really a need for an
Angle
type? I mean, it does no harm, but angles are really just plain numbers and doesn't do anything to distinguish itself from aDouble
. --Ledrug 06:11, 22 September 2012 (UTC)
- I think it's fine. I changed the polyline area function, maybe it's clearer this way. Also added some comments explaining some odd stuff I did in the code. One thing sort of amuses me is, is there really a need for an