|
|
Comments and Discussions
|
|
 |

|
Hi,
Thanks very much for the library!
I am using several distributions from the library for a Monte Carlo simulation. The random number gets repeated unless there is a difference of 15ms between two calls. Is there anyway to overcome the problem?
Achal
|
|
|
|

|
I second this, I put it in a multiple threading code, I got a lot of repteating as well.
|
|
|
|

|
Thank you for great work!
Although.
I need a random value from a limited range (e.g. [0, 1]) generated with a Weibull distribution. The confidency level is ~0.95 or so. Please help me on that.
Thanks again. I am looking forward to your reply.
Greetings - Jacek Gajek
|
|
|
|

|
I created a solution with two projects:
1) Your original desktop CLR generator library project
2) A Silverlight project using links to the first project's .cs files
Only changes to #2 were conditional macros as following:
#if SILVERLIGHT
throw new ArgumentOutOfRangeException("maxValue", message);
#else
throw new ArgumentOutOfRangeException("maxValue", maxValue, message);
#endif
Happy to give you the code to post, or re-upload as a new article if you'd prefer. Couldn't figure out if there's already a standard mechanism for this on CodeProject. You could start a CodePlex site...
|
|
|
|

|
Hi,
First I want to thank you for such a great work!
Second, I think something is wrong with Erlang random drawing. Using Random tester, If you try different Alpha and compare the mean of random numbers and actual mean of the distribution, they do not match at all. It just works when Alpha=1
|
|
|
|

|
Hi,
thanks for the feedback.You're absolutely right: the Erlang distribution is broken for Alpha != 1. I have/had an error in my logic to avoid Math.Log(0.0). Instead of the product of random numbers the single random numbers have to be substracted from 1.0. I changed the NextDouble method as follows:
double product = 1.0;
for (int i = 0; i < this.alpha; i++)
{
product *= (1.0 - this.Generator.NextDouble());
}
return this.helper1 * Math.Log(product);
The fix will be included in the next version. I cannot say when it is coming cause I hadn't much time lately to work on this project and don't when I will have the time. Hope the info above, helps you for now and once again thanks for the feedback.
Regards Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook
|
|
|
|

|
Very interesting and well done stuff.
Code is very clean, well commented and full of nice things.
I would like to give you some ideas i had reading your code about performance and design choices:
1) Using an interface IGenerator instead than an abstract class Generator is more efficient and a more generic approach.
As what i saw in my experience, call to interface members are sometime more performant than virtual call to virtual members.
2) Most of the "override" in inherited classes can be marked as "sealed override".
Or, if you choose the interface approach, you don't even need to put virtual, sealed, override keywords.
Most of the inherited classes can also be marked as "sealed", so, they don't have virtual members and JIT can optimize them better.
I still don't understand why microsoft didn't an IRandom interface!
Sometime some design choices in from .NET team let me think about what kind of weed they smoked
public interface IGenerator
{
int Next();
...
}
public sealed class XorShift128Generator : IGenerator
{
public int Next() { ... }
...
}
...
IGenerator g1 = new XorShift128Generator();
g1.Next();
XorShift128Generator g2 = new XorShift128Generator();
g2.Next();
...
The same thing can be done with Distribution class, and, if you need, you can create an 'intermediate' abstract class with 'utility' members.
public interface IDistribution
{
bool CanReset { get; }
double Minimum { get; }
...
}
public abstract class DistributionBase
{
private IGenerator generator;
public DistributionBase(IGenerator generator) { this.generator = generator; ... }
public bool CanReset { get { return this.generator.CanReset; } }
...
}
public sealed class BinomialDistribution : DistributionBase, IDistribution
{
public double Minimum() { ... }
}
public sealed class MyStrangeDistribution : AnotherObject, IDistribution
{
public bool CanReset { return false; }
...
}
Another nice thing could be to create a base interface between IGenerator and IDistribution.
In this way, you can put common methods like CanReset, Reset, double Next() and so on in this base interface to make the code even more reusable and generic.
And... at last... [Serializable] ... it is useful to make all possible classes serializable.
Serialization in always useful in this world
If you need help refactoring the classes i would be glad to help, the project is quite interesting and well done!
Thanks for your work.
I don't fear computers.
I fear the lack of them.
(Isaac Asimov)
|
|
|
|

|
Hello I don't study mathematics and i needs a source code of the program chi square, t student, and others helpme please...
I speak spanish my english is very bad.... lo siento
helpme please
|
|
|
|

|
hendryck wrote: i needs a source code of the program chi square, t student, and others
Download the source code of the library using the link at the top of the article and take a look at the respective classes.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook
|
|
|
|

|
Your work was so great and comprehensive and it helped me a lot in doing my project!
Thank you a lot!
Ali Nasri Nazif
|
|
|
|

|
Hi,
I see there is a function NextDouble() in the Distribution class and it returns a value between the possible Maximum and Minimum value of the distribution. Is there a way to restrict the numbers produced by the distribution into a smaller interval. Like if you are calling NextDouble() until you get a number in the interval, let's say, [a, b] < [Maximum, Minimum].
Thanks in advance,
Boian
|
|
|
|

|
Sogartar wrote: Is there a way to restrict the numbers produced by the distribution into a smaller interval.
The distributions included in the library provide no general way to restrict the interval of generated values. The numbers produced by a distribution are influenced by their individual parameters, so you can restrict the interval if a concrete distribution provides parameters for the minimum and/or maximum.
Regards Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook
|
|
|
|

|
First of all: Great work !
Do you plan do add additional methods to the distribution classes like Quantiles, calculation of probabilities of intervalls etc. ?
|
|
|
|

|
THX for the praise
Regarding your question: I'm sorry, but currently I have no plans to add functionality to the library, since I do not have much time.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
First of all I'd like to thank you for producing such a comprehensive library.
My code looked something like this to generate Discrete uniformly distributed random numbers between 0.0 and 1.0.
DiscreteUniformDistribution d = new DiscreteUniformDistribution();
And whether i left the Alpha and Beta for the default values or set it to 0 or 1.
i used the NextDouble() method to get a double, but always the generator just generate 0 or 1 values, and no in between numbers.
Thanks alot
|
|
|
|

|
All discrete distributions generate only whole numbers regardless of which Next method you call. In your case you should use the ContinuousUniformDistribution.
Regards Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|

|
I was triing to test Erlang distribution with parameters aplha=2 and lambda=0.4
Theoretically, I should get the average near 2 / 0.4 = 5.0
After 10000 runs my average was 0.8842
The error is in method NextDouble() of class ErlangDistribution
The following statement
return this.helper1 * Math.Log(1.0 - product);
should be rewritten like this
return this.helper1 * Math.Log(product);
Overall I'm very impressed by the library!
Thank you for such great effort!
Herman H.
|
|
|
|

|
Hi and thanks for finding this error. The intention of the substract operation was to avoid Math.Log(0.0), but instead of the product the single random numbers have to be substracted from 1.0. I changed the NextDouble method as follows:double product = 1.0;
for (int i = 0; i < this.alpha; i++)
{
product *= (1.0 - this.Generator.NextDouble());
}
return this.helper1 * Math.Log(product);The change will be included in the next version of the library. I'll try to publish it as soon as possible but since I'm currently reviewing the whole library and write some UnitTest this may take a while.
Once again thx for the input.
Regards Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
MT19937Generator rGen = new MT19937Generator();
Debug.WriteLine("Rgen #: " + rGen.Next()) ;
I ran this code 800 times. New instance of the generator every time. I got the same number on tries 1 - 799. Am I running it wrong?
|
|
|
|

|
The default constructor of the MT19937Generator class (as well as all other generator classes) uses a time-dependent seed (Environment.TickCount). On a fast computer it is very likely that subsequently created instances have the same seed. To see the effect run the following code with and without the Thread.Sleep.
for (int i = 0; i < 10; i++)
{
MT19937Generator gen = new MT19937Generator();
System.Diagnostics.Trace.WriteLine(i + ": " + gen.Next());
System.Threading.Thread.Sleep(1);
}
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
This is just excellent. Thank you for posting this.
|
|
|
|

|
Can someone provide straightforward directions on how to use this Random class in a VC# 2005 project. I've added the project to my solution and set the dependency. But, I can't use the Random Class ... what am I missing?
|
|
|
|

|
After adding the project to your solution, you have to add a reference to it in the project that should use the library and probably add a using directive for the Troschuetz.Random namespace at the top of code files that should use classes from the library.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Thanks ... just what I needed. Thanks for the great library!!
|
|
|
|

|
First of all I'd like to thank you for producing such a comprehensive library.
However, having just spent an hour or so tracking down a bug in my own code, caused by the behaviour of your library, I'd like to suggest a couple of improvements.
My code looked something like this to generate uniformly distributed random numbers between 4.0 and 8.0.
ContinuousUniformDistribution u = new DiscreteUniformDistribution(generator);
u.Alpha = 4.0;
u.Beta = 8.0;
Unfortunately, since Alpha and Beta are implicityly initialized to zero, and the Alpha and Beta property setters check that Alpha < Beta, the u.Alpha = 4.0; silently fails because 4.0 is not less than the current value of Beta == 0.0 at that point. This results in Alpha remaining at zero, although Beta will be set successfully.
You suggest calling IsValidAlpha and IsValidBeta to check the values, but these are called internally by the property setters anyway, and will still fail for the reasons outlined above.
Obviously, the workaroud is
ContinuousUniformDistribution u = new DiscreteUniformDistribution(generator);
u.Beta = 8.0;
u.Alpha = 4.0;
but this is very non-obvious from the API.
May I suggest removing the checks in the Alpha and Beta property setters, and introducing a new AreValidAlphaBeta() so we can do something like:
ContinuousUniformDistribution u = new DiscreteUniformDistribution(generator);
u.Alpha = 4.0;
u.Beta = 8.0;
Debug.Assert(u.AreValidAlphaBeta());
or even
ContinuousUniformDistribution u = new DiscreteUniformDistribution(generator);
Debug.Assert(u.AreValidAlphaBeta(4.0, 8.0));
u.Alpha = 4.0;
u.Beta = 8.0;
Other that this wart, its an excellent library. Thank you again.
|
|
|
|

|
Hi!
First of all, I apologize for the inconvenience caused. I'm truly sorry that this "silent failure" of my library made you waste an hour.
To be honest, I never was fully content with the design of the properties for the distribution parameters and the possibility of "silent failure" it introduces. I chose this design, cause I did not like the idea of throwing exceptions from the property setters but at the same time wanted to prevent invalid configuration of a distribution. I promise you that I will review the design considering your suggestion for which I am grateful. However, I am currently really busy with the completion of my master's thesis, so this must wait till the next month.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Stefan,
No need to apologise. I appreciate having your library - it has saved me far more time than it has cost.
Best of luck with completing your thesis!
Rob
|
|
|
|

|
Actually, the workaround I gave above is not robust in all circumstances. For uniform distributions the following code will work, irrespective of the original and new values of Alpha and Beta.
// A routine to work around the mis-feature in setting alpha and beta
private static void AlphaAndBeta(DiscreteUniformDistribution distribution, int alpha, int beta)
{
distribution.Alpha = Math.Min(alpha, distribution.Alpha);
distribution.Beta = Math.Max(beta, distribution.Beta);
distribution.Alpha = alpha;
distribution.Beta = beta;
Debug.Assert(distribution.Alpha == alpha);
Debug.Assert(distribution.Beta == beta);
}
|
|
|
|

|
I'm having no problems resetting a Standard Generator, but resetting a distribution doesn't seem to be working for me:
Troschuetz.Random.NormalDistribution n = new Troschuetz.Random.NormalDistribution ();
string s1="First Try of 5 Random Numbers: ";
for (int i=1; i<=5; i++)
{
s1+=n.NextDouble() + " ";
}
n.Reset();
string s2= "Second Try of 5 Random Numbers:";
for (int i=1; i<=5; i++)
{
s2+=n.NextDouble () + " ";
}
MessageBox.Show (s1 + "\r\n" + s2);
The above code ought to produce the exact same set of 5 numbers, and it doesn't. What am I doing wrong?
PS. Thank you very much for this--it looks well put together! Sorry if I'm missing something obvious...
|
|
|
|

|
Hi,
thanks for the input and finding this error. The problem is that I've once more forgotten to consider the random number generation algorithm of the normal distribution. It computes two random numbers at a time, buffers one and returns it when the NextDouble method is called for the next time. When I started developing this library I thought it will be sufficient for all distributions to reset the underlying random number generator, but obviously it is not since for example the NormalDistribution has to discard an already computed random number. I've corrected the whole mess by declaring the Distribution.Reset virtual and overriding it in derived classes when necessary. The new version of the library is uploaded.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
This is awesome, thank you a million!
|
|
|
|

|
Hi, my name is Todd and I am a working on a simulation model in VB.NET. I'm a novice programmer and trying to figure things out as I go, but need some help. I need to be able to choose a random number from a normal distribution with a mean and standard deviation (both need to be user defined). Would this library help me? Any suggestions would be extremely helpful. Thanks.
Take care
T
|
|
|
|

|
Hi Todd!
You can customize the normal distribution (and all other distributions too) with help of its (their) parameters exposed as properties. In case of the normal distribution the mean directly maps to the μ parameter and the standard deviation directly maps to the σ parameter. In general, the relation of the parameters to the statistics of a distribution is shown in the respective Wikipedia articles to which the article links.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Thanks a lot for the work. Cheers
|
|
|
|

|
A wonderful bit of work.
I wanted to use your tester program but it gives a zillion problems with respect to the ZedGraph stuff. For example it says that it can't tell if it's using a ZedGraph or a System.Windows Label. If I disambiguate those then I get a bunch of other serious errors.
As I'm sure it worked on your system, I suspect that the problem arises from the fact that I have a recent ZedGraph installation on my PC and for some reason it's clashing with yours. However, my version of the .dll is identical to yours.
Have you any idea of how I can get your Tester working?
Thanks
Steve
|
|
|
|

|
SteveAbbott wrote: As I'm sure it worked on your system
You're right
Nevertheless I checked again and found something strange. Though I copied ZedGraph.dll version 5.0.1.41097 into the RandomTester project and referenced it, Visual Studio tells me in the properties that it references version 4.2.1.35091 at a path that no longer exists and copied it to the output directory (don't know from where). I've experimented a bit, but now everything is messed up and I'm no longer able to let the RandomTester project reference the Random project which is quite essential
I will try to fix this mess on weekend and update the downloads if I succeed.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Thanks for trying! I still get confused about what magic DotNet is doing with control dlls. DotNet is often that sad mixture of Microsoft being so smart that it's dumb.
Good luck with your search for the magic fix. I look forward to experimenting with your excellent code.
Steve
|
|
|
|

|
Got some time tonight and think I fixed it.
It seems it was some weird problem with the VS project. I copied all resources to a new project where I could reference my Random project again and also the ZedGraph.dll version I want. When referencing the version of ZedGraph which I thought using the whole time, I faced the same ambiguity problems as you and they seem to have changed some other things too. So obviously on your computer the VS project didn't show the weird behaviour as on mine.
Cause I didn't want to rewrite the code for the newer ZedGraph version and the RandomTester runs well with the older one, I stick to it and updated the project so it hopefully uses this one correctly on every computer.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
That's brilliant. It all works fine now, thanks for repackaging everything.
I wish I knew a foolproof way of moving a .Net project from one folder to another without all sorts of collateral damage!
Steve
|
|
|
|

|
Hi there, first of all *great* article. Very useful for me.
I was wondering if in your work you have came accross an FInv funtion (return the quantile according to the F distribution - avaialble in Excel FInv).
Thanks a lot,
Busi
|
|
|
|

|
Sorry, but that method never crossed my way.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Thanks Stephan.
If you will, drop me a line...
Thanks,
Busi
|
|
|
|

|
I'll keep my eyes open
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Hello Stefan (again),
Just asking if during your recent work you have come accross the naughty FInv function...
Thanks,
Busi
|
|
|
|

|
Sorry to disappoint you but it still didn't cross my way.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Almost ten years ago I took a class in Simulations and Testing for my CE Masters. In that class I had to hand code a half dozen different random number generators in order to to use them simultaneously for different variables/inputs to guarantee they were related. Boy could I have used something like this back then ... though C# wasn't even on the radar then.
Worth a 5 to me even though I don't have a current need to RNG functions.
One thing though, my text book back then had many examples of bad RNG functions and charts/graphs to show why. They were often time series plots in 3D that would show patterns, etc. If I recall correctly, often it wasn't the algortithm, but the parameters that could make or break an RNG. I no longer have the book, but I was wondering how hard it would be to add such tests to your test app so that you could experiement with the parameters to the different RNG functions &/or create more and be able to spot a bad one.
|
|
|
|

|
Scott S. wrote: how hard it would be to add such tests to your test app
It's hard to say without having/knowing the book you refer to and therefor not knowing how complex these test are.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|

|
Hello
I am trying Random Tester and the DescreteUniformDistribution. And it gives me quite strange results. The histogram is almost OK: the numbers are uniformly distributed, except for 3 points in it. First is the number something less then 1/3 of the range, then the number less then 2/3 of the range and then the upper bound.
If I generate numbers between 0 - 100, than the histogram is OK except for number(s) a bit less than 30 and 60 and at the number 100.
If I generate numbers between 0 - 5000, than the histogram is OK except for number(s) about 1400 and 2900 and 5000. To see this anomaly, you have to increase number of samples (I used 10 000 000)
To see it cleary is goot to not use large range (say 0 - 1000), and use many samples (it's visible in 1 000 000 samples, but much better in 10 000 000 samples).
Can anybody explain this to me?
Thanks a lot, Stano
PS: Great work and thanks a lot for this library.
|
|
|
|

|
Hi,
the described behaviour results from the used computation of the displayed histogram. In case you generate discrete random numbers between 0 and 100 there are 101 discrete numbers that occur. At the same time the histogram uses by default only 100 steps (intervals), so it cannot differentiate all generated numbers.
Therefor increase the number of histogram steps, so it equals at least the number of generated discrete numbers.
Regards, Stefan
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Presents a fully managed class library providing various random number generators and distributions
| Type | Article |
| Licence | |
| First Posted | 8 Aug 2006 |
| Views | 172,516 |
| Downloads | 6,683 |
| Bookmarked | 212 times |
|
|