I hope somebody can be of assistance, thank you in advance.
I am using C# to generate some simulation models for evaluating the medium stationary time of a request in a system and the degree of usage of that serving station from the system.
I am using a function to generate the required numbers:
public double genTP(double miu)
{
Random random = new Random();
double u, x;
u = (double)random.NextDouble();
x = (-1 / miu) * Math.Log(1 - u);
return x;
}
This is the main:
Program p1 = new Program();
double NS = 1000000;
double lambda = 4;
double miu = 10;
double STP = 0;
double STS = 0;
double STL = 0;
double i = 1;
double Ta = 0;
double Tp = 0;
double Dis = 0;
do
{
Tp = p1.genTP(miu);
STP += Tp;
STS += Ta + Tp;
Dis = p1.genDIS(lambda);
if (Dis < Ta + Tp)
{
Ta = Ta + Tp - Dis;
}
else
{
STL += Dis - (Ta + Tp);
Ta = 0;
}
i++;
} while (i <= NS);
Console.WriteLine(STS / NS);
Console.WriteLine((STP/(STP+STL))*100);
1) The medium stationary time (which is r) returned is wrong, I get values like 0.09.. but I should get something like ~0.1665.. The algorithm is ok, I am 100% sure of that, I tried something like that in Matlab and it was good. Also the degree of usage (the last line) returned is ok (around ~39.89), only the r is wrong. Could it be a problem with the function, especially the random function that should generate a number?
2)Regarding my function genTP, if I change the parameter from double to int, then it returns 0 at the end. I used debugger to check why is that, and I saw that when the method calculates the value of x with (-1 / miu), this returns 0 automatically, I have tried to cast to double but with no result. I was thinking that this could be a source of the problem.
You're creating a new instance of Random each time you call genTP. If this is called multiple times in quick succession (as it is) then it will use the same seed each time. See my article on random numbers for more information.
Create a single instance of Random and pass it into the method:
private static double GenerateTP(Random random, double miu)
{
double u = random.NextDouble();
return (-1 / miu) * Math.Log(1 - u);
}
And...
Random random = new Random();
do
{
double tp = GenerateTP(random, miu);
...
}
A few more suggestions:
Declare your variables at the point of first use, with minimal scope
Follow .NET naming conventions
Don't make methods instance methods if they don't use any state
I prefer to create a static random field in the calculation class
static Random random = new Random();
Now I can use it without thinking of quick succession and I don't need to give it as a function parameter (I'm not trying to say it works faster but just similar to mathematical notation)
Regarding your second question, it is because the compiler does an integer division because they are two integers.
int / int = int (and the result is truncated).
If any of the args are floating point types, the operation is promoted to a floating point division. If you change your arg to an int, you should either use -1d (a double with value -1), or cast 'miu' to a double before usage:
x = (-1d / miu) ...
or
x = (-1 / (double)miu) ...
Or, of course, use them both as doubles. I prefer the first way.
Related
I have been practicing c# nowadays and decided to write a code that converts any decimal to any base representation for practice purpose. And i have some troubles. Since i want to practice i decided to do it with an additional function where calculations take place. First i wanted to use an array to keep my result. But since ,at the beginning, i do not know the length of the array i could not define it.So i decided to use list(somehow i assumed undeclared slots are 0 as default). This is what i end up with.
class MainClass
{
static double number;
static double baseToConvert;
static int counter = 0;
static List<double> converted = new List<double>();
public static void Main(string[] args)
{
Console.WriteLine("Enter a decimal");
number = double.Parse(Console.ReadLine());
Console.WriteLine("Enter a base you want to convert to");
baseToConvert = double.Parse(Console.ReadLine());
ConverterToBase(number);
for (int i = converted.Count - 1; i >= 0; i--)
{
Console.WriteLine(converted[i]);
}
Console.ReadLine();
}
public static void ConverterToBase(double x)
{
double temp = x;
while (x >= baseToConvert)
{
x /= baseToConvert;
counter++;
}
converted[counter] = x;
counter = 0;
if (temp - x * Math.Pow(baseToConvert, Convert.ToDouble(counter)) >= baseToConvert)
{
ConverterToBase(temp - x * Math.Pow(baseToConvert, Convert.ToDouble(counter)));
}
else
{
converted[0] = temp - x * Math.Pow(baseToConvert, Convert.ToDouble(counter));
}
}
}
But after i write inputs console gets stuck without an error. My guess is that since i do not have any elements in the list " converted[counter] " does not make sense. But i do not know maybe the problem is somewhere else.
My question is not about the way i calculate the problem(Of course any suggestions are welcomed). I just want to know what i am doing wrong and how i can handle such situation(unknown array size , use of list , accessing a variable,array,.. etc from another method... ).
Thanks.
My previous answer was wrong as pointed out by #Rufus L. There is no infinite for loop. However upon further review, there seems to be an infinite recursion going on in your code in this line:
if (temp - x * Math.Pow(baseToConvert, Convert.ToDouble(counter)) >= baseToConvert)
{
ConverterToBase(temp - x * Math.Pow(baseToConvert, Convert.ToDouble(counter)));
}
ConverterToBase calls itself and there seems to be no base case nor return statement to end the recursion.
In the method named "ConverterToBase(double x)" you want to set value of 0 element. But you didn't add any element. The converted is Empty.
Firstly add value or values to your list.
Have a variable that I give a random range between -2.0f and 2.0f (Random.Range(-2.0f, 2.0f); in Unity/C#), but I don't want it to pick a number between -0.6f and 0.6f.
How do I got about doing this?
http://docs.unity3d.com/ScriptReference/Random.Range.html
The loop thing seems kind of wasteful to me. After all, you could end up generating a bunch of unusable numbers. Why not generate two numbers from the two allowable ranges, then select at random one to return?
var candidates = new[] {Random.Range(-2.0f, -0.6f), Random.Range(0.6f, 2.0f)};
return candidates.OrderBy(c => Random.Next()).First();
You could also do one random number and then decide at random if you should return it as a negative or positive number. The code below also avoids the OrderBy method, which I am informed will not work with Unity and iOS
var rand = Random.Range(0.6f, 2.0f);
if (Random.Range(0, 100) <= 50)
{
rand = rand * -1f;
}
return rand;
Also, though it is, strictly speaking, outside the scope of your original question, if you cannot assume that both ranges are the same (in absolute values), and you also cannot use OrderBy, you could write something like this:
var candidates = new[] {Random.Range(-2.0f, -0.6f), Random.Range(0.6f, 2.0f)};
var idx = Random.Range(0,2); // this should give you either 0 or 1
return candidates[idx];
How about:
var delta = Random.Range(-1.4f, 1.4f);
var result = delta >= 0 ? delta + 0.6f : delta - 0.6f;
Or perhaps:
var delta = Random.Range(-1.4f, 1.4f);
var abs = Mathf.Abs(delta);
var sign = Mathf.Sign(delta);
var result = sign*(0.6f + abs);
EDIT: Changed things around to avoid using the ternary operator and removed a remark that was wrong. Thanks #sh1!
Casey's answer looks fine. I just don't know how to make it work with other values. The answer below provides a re-usable code that will easily work with other values.
It generates the first number. That number it will use to determine if it should generate a number below the min number you want to exclude or a number above the max number you want to exclude. The second number it generates is the actual random number.
float Range(float min, float max, float ignoreFrom, float ignoreToEnd)
{
int dirRand = UnityEngine.Random.Range(1, 3); //1 to 2 random number
float finalRandomNum = 0;
//If 1, generate number below ignoreFrom, min
if (dirRand == 1)
{
ignoreFrom += 0.00001f; //To make make ignoreFrom exclusive (Remove if you want to include it)
finalRandomNum = UnityEngine.Random.Range(ignoreFrom, min);
}
//If 2, generate number above ignoreToEnd
else if (dirRand == 2)
{
ignoreToEnd += 0.00001f; //To make make ignoreToEnd exclusive (Remove if you want to include it)
finalRandomNum = UnityEngine.Random.Range(ignoreToEnd, max);
}
return finalRandomNum;
}
To test it lets generate 80 random numbers between -2.0f and 2.0f with exclusion min -0.6f and max 0.6f.
for (int i = 0; i < 80; i++)
{
Debug.Log(Range(-2f, 2f, -0.6f, 0.6f));
}
This is a formula to approximate arcsine(x) using Taylor series from this blog
This is my implementation in C#, I don't know where is the wrong place, the code give wrong result when running:
When i = 0, the division will be 1/x. So I assign temp = 1/x at startup. For each iteration, I change "temp" after "i".
I use a continual loop until the two next value is very "near" together. When the delta of two next number is very small, I will return the value.
My test case:
Input is x =1, so excected arcsin(X) will be arcsin (1) = PI/2 = 1.57079633 rad.
class Arc{
static double abs(double x)
{
return x >= 0 ? x : -x;
}
static double pow(double mu, long n)
{
double kq = mu;
for(long i = 2; i<= n; i++)
{
kq *= mu;
}
return kq;
}
static long fact(long n)
{
long gt = 1;
for (long i = 2; i <= n; i++) {
gt *= i;
}
return gt;
}
#region arcsin
static double arcsinX(double x) {
int i = 0;
double temp = 0;
while (true)
{
//i++;
var iFactSquare = fact(i) * fact(i);
var tempNew = (double)fact(2 * i) / (pow(4, i) * iFactSquare * (2*i+1)) * pow(x, 2 * i + 1) ;
if (abs(tempNew - temp) < 0.00000001)
{
return tempNew;
}
temp = tempNew;
i++;
}
}
public static void Main(){
Console.WriteLine(arcsin());
Console.ReadLine();
}
}
In many series evaluations, it is often convenient to use the quotient between terms to update the term. The quotient here is
(2n)!*x^(2n+1) 4^(n-1)*((n-1)!)^2*(2n-1)
a[n]/a[n-1] = ------------------- * --------------------- -------
(4^n*(n!)^2*(2n+1)) (2n-2)!*x^(2n-1)
=(2n(2n-1)²x²)/(4n²(2n+1))
= ((2n-1)²x²)/(2n(2n+1))
Thus a loop to compute the series value is
sum = 1;
term = 1;
n=1;
while(1 != 1+term) {
term *= (n-0.5)*(n-0.5)*x*x/(n*(n+0.5));
sum += term;
n += 1;
}
return x*sum;
The convergence is only guaranteed for abs(x)<1, for the evaluation at x=1 you have to employ angle halving, which in general is a good idea to speed up convergence.
You are saving two different temp values (temp and tempNew) to check whether or not continuing computation is irrelevant. This is good, except that you are not saving the sum of these two values.
This is a summation. You need to add every new calculated value to the total. You are only keeping track of the most recently calculated value. You can only ever return the last calculated value of the series. So you will always get an extremely small number as your result. Turn this into a summation and the problem should go away.
NOTE: I've made this a community wiki answer because I was hardly the first person to think of this (just the first to put it down in a comment). If you feel that more needs to be added to make the answer complete, just edit it in!
The general suspicion is that this is down to Integer Overflow, namely one of your values (probably the return of fact() or iFactSquare()) is getting too big for the type you have chosen. It's going to negative because you are using signed types — when it gets to too large a positive number, it loops back into the negative.
Try tracking how large n gets during your calculation, and figure out how big a number it would give you if you ran that number through your fact, pow and iFactSquare functions. If it's bigger than the Maximum long value in 64-bit like we think (assuming you're using 64-bit, it'll be a lot smaller for 32-bit), then try using a double instead.
I'm trying to implement logistic regression by myself writing code in C#. I found a library (Accord.NET) that I use to minimize the cost function. However I'm always getting different minimums. Therefore I think something may be wrong in the cost function that I wrote.
static double costfunction(double[] thetas)
{
int i = 0;
double sum = 0;
double[][] theta_matrix_transposed = MatrixCreate(1, thetas.Length);
while(i!=thetas.Length) { theta_matrix_transposed[0][i] = thetas[i]; i++;}
i = 0;
while (i != m) // m is the number of examples
{
int z = 0;
double[][] x_matrix = MatrixCreate(thetas.Length, 1);
while (z != thetas.Length) { x_matrix[z][0] = x[z][i]; z++; } //Put values from the training set to the matrix
double p = MatrixProduct(theta_matrix_transposed, x_matrix)[0][0];
sum += y[i] * Math.Log(sigmoid(p)) + (1 - y[i]) * Math.Log(1 - sigmoid(p));
i++;
}
double value = (-1 / m) * sum;
return value;
}
static double sigmoid(double z)
{
return 1 / (1 + Math.Exp(-z));
}
x is a list of lists that represent the training set, one list for each feature. What's wrong with the code? Why am I getting different results every time I run the L-BFGS? Thank you for your patience, I'm just getting started with machine learning!
That is very common with these optimization algorithms - the minima you arrive at depends on your weight initialization. The fact that you are getting different minimums doesn't necessarily mean something is wrong with your implementation. Instead, check your gradients to make sure they are correct using the finite differences method, and also look at your train/validation/test accuracy to see if they are also acceptable.
I'm running this class and method
public class DiceRoll
{
static Random _r =new Random();
public int Random6()
{
int n = _r.Next(1, 7);
return n;
}
}
I'm trying to use it inside an if statement in another class like so:
if (input == "d6")
{
int dice = diceRoll.Random6();
Console.WriteLine(dice);
}
my question is this. If I call diceRoll.Random6(); with a multiplier like this diceRoll.Random6() * 2; Is it creating two random numbers and adding them or is it just taking one and multiplying it by two?
I think it's probably the latter but I just wanted to check before I got into convoluted programming.
If it is the latter is there a way to make my program call multiple instances of Random6 without going diceRoll.Random6() + diceRoll.Random6(); That works ok for doing it twice but if I want to do it four or six times it'll become inelegant.
Thanks in advance.
Call the method from within a loop
int result = 0;
for(int i = 0; i < 10; i++)
{
result += Random6();
}
It just generates 1 random number then multiplies it by 2
you can just do it in a loop, or if you want to be fancy
var sum = Enumerable.Range(1, 6).Sum(x => diceRoll.Random6())
which you might want to break down into...
var rolls = Enumerable.Range(1, 6).Select(x => diceRoll.Random6()).ToList();
var sumOfRolls = rolls.Sum();
that way you have the sum and a list of each individual roll.