Monte Carlo Pi not accurate - c#

I am having trouble with my Monte Carlo Pi program calculating properly.
Basically, pi is only displaying up to 2 decimal points only at the moment, and I feel the calculation has gone wrong somewhere as the closest pi calculation as number gets higher is 2.98-3.04.
My code is pasted below.
static void Main(string[] args)
{
double n;
double count;
double c = 0.0;
double x = 0.0, y = 0.0;
double pi;
string input;
Console.WriteLine("Please input a number of dots for Monte Carlo to calculate pi.");
input = Console.ReadLine();
n = double.Parse(input);
Random rand = new Random();
for (int i = 1; i < n; i++ )
{
x = rand.Next(-1, 1);
y = rand.Next(-1, 1);
if (((x * x) + (y * y) <= 1))
c++;
pi = 4.0 * ( c / i );
Console.WriteLine("pi: {0,-10:0.00} Dots in square: {1,-15:0} Dots in circle: {2,-20:0}", pi, i, c);
}
}

These calls
x = rand.Next(-1, 1);
y = rand.Next(-1, 1);
give you an integer. But you need doubles:
x = rand.NextDouble() * 2 - 1;
y = rand.NextDouble() * 2 - 1;

The random numbers should be generated between 0 and 1 and not -1 and 1.
Used this fixed version of your code as "mysterious code" for students.
using System;
namespace mysCode
{
class Program
{
static double euclideanDistance(double x1, double y1, double x2, double y2)
{
double dX = x2 - x1;
double dY = y2 - y1;
return Math.Sqrt(dX * dX + dY * dY);
}
static void Main(string[] args)
{
double n;
double c = 0.0;
double x = 0.0, y = 0.0;
double result;
string input;
Console.WriteLine("Quick, pick an integer");
input = Console.ReadLine();
n = double.Parse(input);
Random rand = new Random();
for (int i = 1; i <= n; i++)
{
x = rand.NextDouble();
y = rand.NextDouble();
if (euclideanDistance(x, y, 0, 0) <= 1)
c++;
result = 4.0 * (c / i);
Console.WriteLine("Result: " + result);
}
Console.ReadKey();
}
}
}
It coverages very slowly, I get 3.14152314152314 after 1M iterations.

Related

What does "-?" as double type represent in C#?

So I'm running iterations with this formula:
double x = 10 / 0.25 * ((0.0002 * x1 * (10 - 0.25 * x1)) + 0.00217 * x2 * (20 - 0.25 * x2)); With this process: Xn+1 = f(Xn).
And if you start from negative X you will eventually end up with (-/+) infinity, so after 6 iterations I'm supposed to get infinity, but what I got surprised me and I couldn't find anywhere what that is, I got "-?", I've tried comparing it to +/- infinity and tried to compare it to int numbers just to clarify what it is, but I cant get anything out of it, for example, I've tried if ("-?" > 1000) break;, and it doesn't outcome as "true". Neither am I getting any errors by comparing it to int/double, I need to stop iterations when I start going into infinity, how can I do that?
code:
public static double CalculateX1(double x1, double x2)
{
double x = 10 / 0.25 * ((0.0002 * x1 * (10 - 0.25 * x1)) + 0.00217 * x2 * (20 - 0.25 * x2));
return x;
}
public static double CalculateX2(double x2, double x1)
{
double y = 20 / 0.25 * ((0.00052 * x2 * (20 - 0.25 * x2)) + 0.0075 * x1 * (10 - 0.25 * x1));
return y;
}
static void Main(string[] args)
{
string writePath = #"C:\Users\evluc\Desktop\cord.txt";
double X = -5;
double Y = -5;
int pointer = 1;
double[,] coordinates = new double[10001, 2];
coordinates[0, 0] = X;
coordinates[0, 1] = Y;
for (int i = 0; i < 5000; i++)
{
//double XTemp = CalculateX1(X, Y);
//double YTemp = CalculateX2(Y, X);
//X = CalculateX1(coordinates[pointer - 1, 0], coordinates[pointer - 1, 1]);
//Y = CalculateX2(coordinates[pointer - 1, 1], coordinates[pointer - 1, 0]);
coordinates[pointer, 0] = CalculateX1(coordinates[pointer - 1, 0], coordinates[pointer - 1, 1]);
coordinates[pointer, 1] = CalculateX2(coordinates[pointer - 1, 1], coordinates[pointer - 1, 0]);
pointer++;
if (Math.Abs(coordinates[pointer, 0]) > 1000 || Math.Abs(coordinates[pointer, 1]) > 1000)
{
Console.WriteLine("infinity");
Console.ReadKey();
}
}
for (int i = 0; i < 5000; i++)
{
Console.WriteLine("X = " + coordinates[i, 0] + "," + "Y = " + coordinates[i, 1] + "; ");
}
}
I think whatever you use to display/inspect the value cannot print ∞.
double d = double.MinValue;
d *= 2;
Console.WriteLine($"{d}: IsInfinity: {double.IsNegativeInfinity(d)}");
-∞: IsInfinity: True
Stopping at infinity
Here's a loop that stops at infinity:
double d = 2;
var i = 1;
while(!double.IsInfinity(d))
{
d = i*d*d;
i = -i;
}
Console.WriteLine(d);
-∞

Homomorphic Filter implementation in Frequency domain [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I have found various formulas for Frequency Domain representation of Homomorphic Filter. I am using the following one:
Where, D(u, v) is:
I have implemented it following the same pattern of source code as the FFT Gabor Filter.
Source Code
private Array2d<Complex> HomoMorphicFilterFft(double M, double N, double yH, double yL, double c, double D0)
{
Array2d<Complex> kernel = new Array2d<Complex>((int)M, (int)N);
for (double y = 0; y < N; y++)
{
double v = y / N;
for (double x = 0; x < M; x++)
{
double u = x / M;
double kw = HMFft(u, v, M, N, yH, yL, c, D0);
kernel[(int)x, (int)y] = new Complex(kw, 0);
}
}
return kernel;
}
private double HMFft(double u, double v, double M, double N, double yH, double yL, double c, double D0)
{
double p = u - M / 2;
double q = v - N / 2;
double Duv = Math.Sqrt(p * p - q * q);
double d = (Duv / D0) * (Duv / D0);
double e = Math.Exp((-1) * c * d);
double homo = (yH - yL) * (1-e) + yL;
return homo;
}
}
The kernel formula is generating NaN.
What am I doing incorrectly on this occasion?
Update: I followed Duurt's answer and the output was not coming:
Then I did some modification in the source code:
Array2d<double> dOutput = Rescale2d.Rescale(DataConverter2d.ToDouble(cOutput));
is replaced by
Array2d<double> dOutput = Rescale2d.Limit(DataConverter2d.ToDouble(cOutput));
And,
Array2d<double> dLimitedKernel = Rescale2d.Limit(dKernel);
is replaced by
Array2d<double> dLimitedKernel = Rescale2d.Rescale(dKernel);
But, the output is still not the expected one:
The expected output is something like the following (or, is it?):
The difference between Limit() and Rescale() is: Limit() trims only those values that exceed the range of 0-1. Rescale() rescales all values in the array by dividing them with maximum value in the array.
.
Source Code
The following is the more detailed source code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bitmap image = DataConverter2d.ReadGray(StandardImage.LenaGray);
Array2d<double> dImage = DataConverter2d.ToDouble(image);
int newWidth = Tools.ToNextPowerOfTwo(dImage.Width);
int newHeight = Tools.ToNextPowerOfTwo(dImage.Height);
double yH = 2;//2;
double yL = 0.5;//0.5;
double c = 0.5;
double D0 = 1;//0.5;
Array2d<Complex> kernel2d = HomoMorphicFilterFft(newWidth, newHeight, yH, yL, c, D0);
dImage.PadTo(newWidth, newHeight);
Array2d<Complex> cImage = DataConverter2d.ToComplex(dImage);
Array2d<Complex> fImage = FourierTransform.ForwardFft(cImage);
// FFT convolution .................................................
Array2d<Complex> fOutput = new Array2d<Complex>(newWidth, newHeight);
for (int x = 0; x < newWidth; x++)
{
for (int y = 0; y < newHeight; y++)
{
fOutput[x, y] = fImage[x, y] * kernel2d[x, y];
}
}
Array2d<Complex> cOutput = FourierTransform.InverseFft(fOutput);
// trims the values to keep them between 0 and 1.
Array2d<double> dOutput = Rescale2d.Limit(DataConverter2d.ToDouble(cOutput));
dOutput.CropBy((newWidth - image.Width) / 2, (newHeight - image.Height) / 2);
Bitmap output = DataConverter2d.ToBitmap(dOutput, image.PixelFormat);
Array2d<Complex> cKernel = FourierTransform.InverseFft(kernel2d);
cKernel = FourierTransform.RemoveFFTShift(cKernel);
Array2d<double> dKernel = DataConverter2d.ToDouble(cKernel);
// Rescales the values to keep them between 0 and 1.
Array2d<double> dLimitedKernel = Rescale2d.Rescale(dKernel);
Bitmap kernel = DataConverter2d.ToBitmap(dLimitedKernel, image.PixelFormat);
pictureBoxExt1.Image = image;
pictureBoxExt2.Image = kernel;
pictureBoxExt3.Image = output;
}
private Array2d<Complex> HomoMorphicFilterFft(double M, double N, double yH, double yL, double c, double D0)
{
Array2d<Complex> kernel = new Array2d<Complex>((int)M, (int)N);
for (double y = 0; y < N; y++)
{
double v = y / N;
for (double x = 0; x < M; x++)
{
double u = x / M;
double kw = HMFft(u, v, M, N, yH, yL, c, D0);
kernel[(int)x, (int)y] = new Complex(kw, 0);
}
}
return kernel;
}
private double HMFft(double u, double v, double M, double N, double yH, double yL, double c, double D0)
{
double p = u - M / 2;
double q = v - N / 2;
double Duv = Math.Sqrt(p * p + q * q);
double d = (Duv / D0) * (Duv / D0);
double e = Math.Exp((-1) * c * d);
double homo = (yH - yL) * (1-e) + yL;
return homo;
}
}
Only concentrate on the algorithm at this time.
Duv has a minus in the Sqrt, while in the formula it has a plus sign. Taking the Sqrt of a negative number could explain your problem.

Matrix Multiplication returning wrong value

I am calculating values by using weights and bias from MATLAB trained ANN. trying to code a sigmoid simulation equation, but for some reason C# calculations vary too much than that of MATLAB. i.e. error is too high. I tried to check each step of the equation and found out the specific part that is creating the problem (Emphasized part), but I don't know how to solve this issue, if someone could help, would be a huge favour.
1+(purelin(net.LW{2}×(tansig(net.IW{1}×(1-(abs(2×([inputs]-1)))))+net.b{1}))+net.b{2}))/2
//Normalization of Data
public double Normalization(double x, double xMAx, double xMin)
{
double xNorm = 0.0;
xNorm = (x - xMin) / (xMAx - xMin);
if (xNorm < 0)
xNorm = 0;
if (xNorm > 1)
xNorm = 1;
xNorm = Math.Round(xNorm, 4);
return xNorm;
}
// Equation to calculate ANN based Output Values
public double MetrixCalc(double[] Pn, double[,] W1, double[] W2, double[] b1, double b2, double maxValue, double minValue)
{
double FinalValue = 0;
double[] PnCalc1 = new double[Pn.Length];
double[] PnCalc2 = new double[W1.Length / Pn.Length];
for (int i = 0; i < Pn.Length; i++)
{
PnCalc1[i] = 1 - Math.Abs(2 * (Pn[i] - 1));
}
for (int i = 0; i < (W1.Length / Pn.Length); i++)
{
double PnCalc = 0.0;
for (int j = 0; j < Pn.Length; j++)
{
PnCalc = PnCalc + (W1[i, j] * PnCalc1[j]);
}
PnCalc2[i] = PnCalc;
}
for (int i = 0; i < PnCalc2.Length; i++)
{
//PnCalc2[i] = Math.Tanh(PnCalc2[i] + b1[i]);
PnCalc2[i] = PnCalc2[i] + b1[i];
PnCalc2[i] = 2.0 / (1 + Math.Exp(-2 * (PnCalc2[i]))) - 1;
PnCalc2[i] = Math.Round(PnCalc2[i], 4);
}
double FinalCalc = 0.0;
for (int i = 0; i < PnCalc2.Length; i++)
{
*FinalCalc = FinalCalc + (W2[i] * (PnCalc2[i]));*
//FinalValue = FinalCalc;
}
FinalValue = FinalCalc + b2;
FinalValue = 1 + FinalValue;
FinalValue = (1 + FinalValue) / 2.0;
FinalValue = (FinalValue * (maxValue - minValue)) + minValue;
FinalValue = Math.Round(FinalValue, 4);
FinalValue = Math.Abs(FinalValue);
return FinalValue;
}
Problem is solved.
Problem was with the weights matrix copied from MATLAB. debugging mode saved my life. :)

Laplace Transform And Getting The Frequent Value For Gyro

I'm getting x,y,z values from gyro-sensor. Each variable is being sent 10 values per second. In 3 seconds I have;
x=[30values]
y=[30values]
z=[30values]
Some of the values are too different from the others cause of noise. With laplace transform I need to get the most frequent value from my array.
I need to filter the array with Laplace Transform equation. I need to build the equation in C#. How can I implement the array with the equation?
Since this kind of filter (Laplace) is very specialized to certain area of Engineering and needs a person who has good understanding on both the programming language (in this case is C#) and the filter itself, I would recommend you to use such source, rather than code the filter by yourself.
Here is the snippet of the source code:
class Laplace
{
const int DefaultStehfest = 14;
public delegate double FunctionDelegate(double t);
static double[] V; // Stehfest coefficients
static double ln2; // log of 2
public static void InitStehfest(int N)
{
ln2 = Math.Log(2.0);
int N2 = N / 2;
int NV = 2 * N2;
V = new double[NV];
int sign = 1;
if ((N2 % 2) != 0)
sign = -1;
for (int i = 0; i < NV; i++)
{
int kmin = (i + 2) / 2;
int kmax = i + 1;
if (kmax > N2)
kmax = N2;
V[i] = 0;
sign = -sign;
for (int k = kmin; k <= kmax; k++)
{
V[i] = V[i] + (Math.Pow(k, N2) / Factorial(k)) * (Factorial(2 * k)
/ Factorial(2 * k - i - 1)) / Factorial(N2 - k)
/ Factorial(k - 1) / Factorial(i + 1 - k);
}
V[i] = sign * V[i];
}
}
public static double InverseTransform(FunctionDelegate f, double t)
{
double ln2t = ln2 / t;
double x = 0;
double y = 0;
for (int i = 0; i < V.Length; i++)
{
x += ln2t;
y += V[i] * f(x);
}
return ln2t * y;
}
public static double Factorial(int N)
{
double x = 1;
if (N > 1)
{
for (int i = 2; i <= N; i++)
x = i * x;
}
return x;
}
}
coded by Mr. Walt Fair Jr. in CodeProject.

Drawing a quadratic curve

Im trying to draw a parabala on a chart, which i have switched to a line graph.
private void calculate_Click(object sender, EventArgs e)
{
double numberA = Convert.ToDouble(valueA.Text);
double numberB = Convert.ToDouble(valueB.Text);
double numberC = Convert.ToDouble(valueC.Text);
displayFormula();
double answer1 = quadCalculator1(numberA, numberB, numberC);
double answer2 = quadCalcualtor2(numberA, numberB, numberC);
quadOutput.Text += answer1 + " OR " + answer2;
this.chart1.Series["quadGraph"].Points.AddXY(answer1, 0);
this.chart1.Series["quadGraph"].Points.AddXY(answer2, 0);
this.chart1.Series["quadGraph"].Points.AddXY(0, numberC);
}
However the output is a straight line, i take it i need more points?
In short, yes you do need more data points.
What you have are the points where the plot intercepts the x and y axes, and plotting these 3 is a good start but the charting engine has no way of interpreting what sort of data set these three points come from (sin, cos and sawtooth plots for example could all be found which include the same intercepts as any quadratic).
If you want to plot an approximation of the curve itself, a quick and dirty solution would be to take the difference between answer 1 and answer 2 (being careful of the situations where they're equal or imaginary) and calculate the y values for a set of points starting some proportion below the lowest answer and the same proportion above the highest answer. You could then simply spin through the results and add them one at a time.
private void calculate_Click(object sender, EventArgs e)
{
double numberA = Convert.ToDouble(valueA.Text);
double numberB = Convert.ToDouble(valueB.Text);
double numberC = Convert.ToDouble(valueC.Text);
displayFormula();
double answer1 = quadCalculator1(numberA, numberB, numberC);
double answer2 = quadCalcualtor2(numberA, numberB, numberC);
quadOutput.Text += answer1 + " OR " + answer2;
//this.chart1.Series["quadGraph"].Points.AddXY(answer1, 0);
//this.chart1.Series["quadGraph"].Points.AddXY(answer2, 0);
//this.chart1.Series["quadGraph"].Points.AddXY(0, numberC);
// Do error checking here to determine validity of answers
// and which is the highest and lowest of the pair
int count = 20;
double[,] data = GetPoints(numberA, numberB, numberC, answer1, answer2, count);
for(int i = 0; i < count; i++)
{
this.chart1.Series["quadGraph"].Points.AddXY(data[i, 0], data[i, 1]);
}
}
private double[,] GetPoints(double a, double b, double c, double xInterceptLow, double xInterceptHigh, int pointCount)
{
double[,] output = new double[pointCount,2];
double subRange = xInterceptLow - xInterceptHigh;
double delta = (2* subRange) / pointCount;
double xMin = xInterceptLow - (subRange/2);
double xMax = xInterceptHigh + (subRange/2);
for(int i = 0; i < pointCount; i++)
{
double x = xMin + ( i * delta);
double ans = GetY(a, b, c, x);
output[i, 0] = x;
output[i, 1] = ans;
}
return output;
}
private double GetY(double a, double b, double c, double x)
{
double answer = (a * a * x) + (b * x) + c;
return answer;
}
Thanks. I added a for loop that calculates 20 values for the coordinates.
for (int i = -10; i < 10; i++)
{
double pointX = i;
double pointY = anyQuad(answer1, answer2, numberA, numberB, numberC, pointX);
this.chart1.Series["quadGraph"].Points.AddXY(pointX, pointY);
}
Works nicely for anyone who needs it!

Categories