Generate a random double between 1 and max in c++/cli - c++-cli

How would i generate a random double between 1 and a defined max in c++/cli, ive use random_number_distribution and mersenne twister in the random header before but never in cli, will this work in cli with random or system::random, or are there any similar alternatives? Thanks.

Here's how
double randDouble(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}

The System::Random class, with its NextDouble method is what you want. NextDouble will return a double >= 0.0 and < 1.0. So, to return a value between 1 and a max:
double RandOneToMax(double max)
{
Random^ r = ...;
return (r->NextDouble() * (max - 1)) + 1;
}

Related

Round outcome Fraction Apache Math Common

Is it possible to round the fraction, e.g., 3/2 becomes 1+1/2 and 11/2 becomes 5+1/2 that is produced using Apache Common Math?
Attempt
Fraction f = new Fraction(3, 2);
System.out.println(f.abs());
FractionFormat format = new FractionFormat();
String s = format.format(f);
System.out.println(s);
results in:
3 / 2
3 / 2
It looks like what you are looking for is a Mixed Number.
Since I don't think Apache Fractions has this built in, you can use the following custom formatter:
public static String formatAsMixedNumber(Fraction frac) {
int sign = Integer.signum(frac.getNumerator())
* Integer.signum(frac.getDenominator());
frac = frac.abs();
int wholePart = frac.intValue();
Fraction fracPart = frac.subtract(new Fraction(wholePart));
return (sign == -1 ? "-" : "")
+ wholePart
+ (fracPart.equals(Fraction.ZERO) ? ("") : ("+" + fracPart));
}

What is the Modulo function for negative decimals Objective-C?

I need to calculate modulos with decimals that can be negative as well
for example: fmod( -5.2, 3 );
while mod() works with integers, and fmod() (or fmodf()) works well with decimals, fmod() returns wrong results with negative decimals:
ex:
double modulo = fmod (5.2, 3);
NSLog (#"==> %f", modulo);
==> 2.2 // This is correct !!
double modulo = fmod (-5.2, 3);
NSLog (#"==> %f", modulo);
==> -2.2 // This is wrong !! should be 0.8
Is there another mod() in the library or should i write my own decimal negative mod function ?
something like :
if (res = fmod(x,m) < 0) {
res+=m;
}
Thx !
-2.2 is correct and is also -5.2 mod 3. The fmod function is a C function (and therefore also Objective C), so you can find more detail about it by typing man fmod into terminal. When doing fmod it will preserve the sign of the value that you are moding. So to get the mod you want, you will need to check the sign (of either the result, or the value you are passing in) and if it is negative you will need to add the modulo base, in this case 3.
This is the definition of the fmod function:
double
fmod(double x, double y);
Specifically, the functions return the value x-i*y, for some integer i such that, if y is non-zero, the result has the same sign as x and magnitude less than the magnitude of y.
from the OS X man page.
For your purposes, you can do something like this:
#include <math.h>
float f_mod(float a, float n) {
return a - n * floor(a / n);
}
Of course, be careful to check n>0.
f_mod(-5.2f, 2.0f) = 0.8
f_mod(5.2f, 2.0f) = 2.2
Thank you so i ended up writing a wrapper... What i was hopping i could avoid. This works great for me, and, in my opinion, represents the correct mathematical definition of the modulo (not the C implementation). I am sure this function can be optimized,but for clarity i leave it this way:
//--
//-- Modulo
//--
double calcModulo ( double x, double m) {
double res = INFINITY;
if (m==0)
return res ;
double posMod, negMod, posM, posX;
posM = m < 0 ? -m:m;
posX = x < 0 ? -x:x;
posMod = fmod (posX, posM);
negMod = fmod (-posX,posM) + posM;
// pick up the correct res
if ( x >= 0 ){
if (m > 0) {
res = posMod;
} else {
res = -negMod;
}
}else{
if (m > 0) {
res= negMod;
} else{
res= -posMod;
}
}
return res;
}

Is there a linspace() like method in Math.Net

Is there function in Math.Net like (MatLab/Octave/numpy)'s linspace() which takes 3 parameters (min, max, length) and creates an vector/array of evenly spaced values between min and max? It is not hard to implement but if there was a function already I would prefer to use that.
There is none exactly like linspace, but the signal generator comes quite close and creates an array:
SignalGenerator.EquidistantInterval(x => x, min, max, len)
I'm not fresh on the VB.net syntax, but I guess it's very close to C#.
In case you need a vector:
new DenseVector(SignalGenerator.EquidistantInterval(x => x, min, max, len))
Or you could implement it e.g. using the static Create function (in practice you may want to precompute the step):
DenseVector.Create(len, i => min + i*(max-min)/(len - 1.0))
Update 2013-12-14:
Since v3.0.0-alpha7 this is covered by two new functions:
Generate.LinearSpaced(length, a, b) -> MATLAB linspace(a, b, length)
Generate.LinearRange(a, [step], b) -> MATLAB a:step:b
I used this C# code to replicate the functionality of linspace (how numpy does it), feel free to use it.
public static float[] linspace(float startval, float endval, int steps)
{
float interval = (endval / MathF.Abs(endval)) * MathF.Abs(endval - startval) / (steps - 1);
return (from val in Enumerable.Range(0,steps)
select startval + (val * interval)).ToArray();
}
Here is the VB Translation I made.
Public Function linspace(startval As Single, endval As Single, Steps As Integer) As Single()
Dim interval As Single = (endval / Math.Abs(endval)) *(Math.Abs(endval - startval)) / (Steps - 1)
Return (From val In Enumerable.Range(0, Steps) Select startval + (val * interval)).ToArray()
End Function
Use examples;
C#
float[] arr = linspace(-4,4,5)
VB
Dim arr as Single() = linspace(-4,4,5)
Result:
-4,-2,0,2,4
I checked the result from the code shown below and MATLAB linspace, it exactly matches. I myself use it for my research work in Monte Carlo implementations.
Below is the code image and the actual code.
static double[] LINSPACE(double StartValue, double EndValue, int numberofpoints)
{
double[] parameterVals = new double[numberofpoints];
double increment = Math.Abs(StartValue - EndValue) / Convert.ToDouble(numberofpoints - 1);
int j = 0; //will keep a track of the numbers
double nextValue = StartValue;
for (int i = 0; i < numberofpoints; i++)
{
parameterVals.SetValue(nextValue, j);
j++;
if (j > numberofpoints)
{
throw new IndexOutOfRangeException();
}
nextValue = nextValue + increment;
}
return parameterVals;
}
Code for creating a linspace function in C#

Generate Random Numbers Between Two Numbers in Objective-C

I have two text boxes and user can input 2 positive integers (Using Objective-C). The goal is to return a random value between the two numbers.
I've used "man arc4random" and still can't quite wrap my head around it. I've came up with some code but it's buggy.
float lowerBound = lowerBoundNumber.text.floatValue;
float upperBound = upperBoundNumber.text.floatValue;
float rndValue;
//if lower bound is lowerbound < higherbound else switch the two around before randomizing.
if(lowerBound < upperBound)
{
rndValue = (((float)arc4random()/0x100000000)*((upperBound-lowerBound)+lowerBound));
}
else
{
rndValue = (((float)arc4random()/0x100000000)*((lowerBound-upperBound)+upperBound));
}
Right now if I put in the values 0 and 3 it seems to work just fine. However if I use the numbers 10 and 15 I can still get values as low as 1.0000000 or 2.000000 for "rndValue".
Do I need to elaborate my algorithm or do I need to change the way I use arc4random?
You could simply use integer values like this:
int lowerBound = ...
int upperBound = ...
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
Or if you mean you want to include float number between lowerBound and upperBound? If so please refer to this question: https://stackoverflow.com/a/4579457/1265516
The following code include the minimum AND MAXIMUM value as the random output number:
- (NSInteger)randomNumberBetween:(NSInteger)min maxNumber:(NSInteger)max
{
return min + arc4random_uniform((uint32_t)(max - min + 1));
}
Update:
I edited the answer by replacing arc4random() % upper_bound with arc4random_uniform(upper_bound) as #rmaddy suggested.
And here is the reference of arc4random_uniform for the details.
Update2:
I updated the answer by inserting a cast to uint32_t in arc4random_uniform() as #bicycle indicated.
-(int) generateRandomNumberWithlowerBound:(int)lowerBound
upperBound:(int)upperBound
{
int rndValue = lowerBound + arc4random() % (upperBound - lowerBound);
return rndValue;
}
You should avoid clamping values with mod (%) if you can, because even if the pseudo-random number generator you're using (like arc4random) is good at providing uniformly distributed numbers in its full range, it may not provide uniformly distributed numbers within the restricted modulo range.
You also don't need to use a literal like 0x100000000 because there is a convenient constant available in stdint.h:
(float)arc4random() / UINT32_MAX
That will give you a random float in the interval [0,1]. Note that arc4random returns an integer in the interval [0, 2**32 - 1].
To move this into the interval you want, you just add your minimum value and multiply the random float by the size of your range:
lowerBound + ((float)arc4random() / UINT32_MAX) * (upperBound - lowerBound);
In the code you posted you're multiplying the random float by the whole mess (lowerBound + (upperBound - lowerBound)), which is actually just equal to upperBound. And that's why you're still getting results less than your intended lower bound.
Objective-C Function:
-(int)getRandomNumberBetween:(int)from to:(int)to
{
return (int)from + arc4random() % (to-from+1);
}
Swift:
func getRandomNumberBetween(_ from: Int, to: Int) -> Int
{
return Int(from) + arc4random() % (to - from + 1)
}
Call it anywhere by:
int OTP = [self getRandomNumberBetween:10 to:99];
NSLog(#"OTP IS %ld",(long)OTP);
NSLog(#"OTP IS %#",[NSString stringWithFormat #"%ld",(long)OTP]);
For Swift:
var OTP: Int = getRandomNumberBetween(10, to: 99)
In Swift:
let otp = Int(arc4random_uniform(6))
Try this.

Optimizing division/exponential calculation

I've inherited a Visual Studio/VB.Net numerical simulation project that has a likely inefficient calculation. Profiling indicates that the function is called a lot (1 million times plus) and spends about 50% of the overall calculation within this function. Here is the problematic portion
Result = (A * (E ^ C)) / (D ^ C * B) (where A-C are local double variables and D & E global double variables)
Result is then compared to a threshold which might have additional improvements as well, but I'll leave them another day
any thoughts or help would be appreciated
Steve
The exponent operator (Math.Pow) isn't very fast, there is no dedicated CPU instruction for calculating it. You mentioned that D and E are global variables. That offers a glimmer of hope to get it faster, if you can isolate their changes. Rewriting the equation using logarithms:
log(r) = log((a x e^c) / (b x d^c))
= log(a x e^c) - log (b x d^c)
= log(a) + log(e^c) - log(b) - log(d^c)
= log(a) + c*log(e) - log(b) - c*log(d)
= log(a) - log(b) + c x (log(e) - log(d))
result = exp(r)
Which provides this function to calculate the result:
Function calculate(ByVal a As Double, ByVal b As Double, ByVal c As Double, ByVal d As Double, ByVal e As Double) As Double
Dim logRes = Math.Log(a) - Math.Log(b) + c * (Math.Log(e) - Math.Log(d))
Return Math.Exp(logRes)
End Function
I timed it with the StopWatch class, it is exactly as fast as your original expression. Not a coincidence of course. You'll get ahead by somehow being able to pre-calculate the Math.Log(e) - Math.Log(d) term.
One easy speed up is that
Result = (A/B) * (E/D)^C
At least you are doing one less exponent.
Depending on what C is, there might be faster ways. Like if C is a small integer.
edit:
adding proof to show this is faster
public static void main(String[] args) {
StopWatch sw = new StopWatch();
float e = 1.123F;
float d = 4.456F;
float c = 453;
sw.start();
int max = 5000;
double result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = (a * (Math.pow(e, c))) / (Math.pow(d, c) * b);
}
}
sw.split();
System.out.println("slow: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
sw.start();
result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = a / b * Math.pow(e/d, c);
}
}
sw.split();
System.out.println("fast: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
}
This is the output
slow: 26062 result: 7.077390271736578E-272
fast: 12661 result: 7.077392136525382E-272
There is some skew in the numbers. I would think that the faster version is more exact (but that's just a feeling since i can't think of exactly why).
Well done for profiling. I would also check that A-C are different on every call. In other words, is it possible the caller is actually calculating the same value over and over again? If so, change it so it caches the answer.
For Math.Floor() function, visit:
http://bitsbyta.blogspot.com/2010/12/math-floor-function-vbnet.html
All functions of math library in vb.net is available at:
http://www.bitsbyta.blogspot.com/