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!
Related
So I have to make a program that prints how many times it has to make a certain calculation. However, when I print the result, I seem to be getting 16000 numbers that just add +1 every new time. My question is how to fix this. I have no idea...
Thank you for your help!
My code:
class Program
{
static void Main(string[] args)
{
double a = 0;
double b = 0;
double distance = 0;
int i = 1;
for (double x = -2; x < 2; x = x+0.01)
{
for (double y = -2; y < 2; y = y+ 0.01)
{
while(distance <= 2 || i < 100)
{
a = a * a - b * b + x;
b = 2 * a * b + y;
double a2b2 = Math.Pow(a, 2) + Math.Pow(b, 2);
distance = Math.Sqrt(a2b2);
i++;
}
Console.WriteLine(i);
}
}
Console.ReadKey();
}
}
I assume you're trying to plot a fractal of some description - I haven't checked the maths, but it reminds me of code I've used to generate Mandelbrot set images before now.
The problem is that you should be creating an independent calculation for each point - but you're maintaining the state of a, b, i and distance between points. That means once distance has become greater than 2 and i is greater than 100, you'll never get into the inside of the while loop. Just move the declaration and initialization of those variables to inside your inner for loop.
Additionally, the conditions for your while loop should be ANDed together rather than ORed together, assuming that the idea is to effectively limit it to 100 iterations per point.
for (double x = -2; x < 2; x += 0.01)
{
for (double y = -2; y < 2; y += 0.01)
{
// Initialize the local variables here, as they're meant to be independent for each point.
double a = 0;
double b = 0;
double distance = 0;
int i = 1;
while (distance <= 2 && i < 100)
{
a = a * a - b * b + x;
b = 2 * a * b + y;
double a2b2 = Math.Pow(a, 2) + Math.Pow(b, 2);
distance = Math.Sqrt(a2b2);
i++;
}
Console.WriteLine(i);
}
}
The double type means floating point type. See wiki. This type is not the right numeric type for precise addition like you use. Instead of that use decimal type.
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.
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. :)
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.
Hello guys i am trying plotting the mandlebrot fractal but the result is very far from it, can you help me to find the why?
Here is the code:
void Button1Click(object sender, EventArgs e)
{
Graphics g = pbx.CreateGraphics();
Pen p = new Pen(Color.Black);
double xmin = -2.0;
double ymin = -1.2;
double xmax = 0;
double ymax = 0;
double x = xmin, y = ymin;
int MAX = 1000;
double stepY = Math.Abs(ymin - ymax)/(pbx.Height);
double stepX = Math.Abs(xmin - xmax)/(pbx.Width);
for(int i = 0; i < pbx.Width; i++)
{
y = ymin;
for(int j = 0; j < pbx.Height; j++)
{
double rez = x;
double imz = y;
int iter = 0;
while(rez * rez + imz * imz <= 4 && iter < MAX)
{
rez = rez * rez - imz * imz + x;
imz = 2 * rez * imz + y;
iter++;
}
if(iter == MAX)
{
p.Color = Color.Black;
g.DrawRectangle(p, i, j, 1, 1);
}
else
{
p.Color = Color.White;
g.DrawRectangle(p, i, j, 1, 1);
}
y += stepY;
}
x += stepX;
}
}
please help me my mind is getting crushed thinking how to get the beautiful mandlebrot set...
and sorry if i committed some mistakes but English is not my speaked language!
You have some irregularities elsewhere. The range you're plotting isn't the entire set, and I would calculate x and y directly for each pixel, rather than using increments (so as to avoid rounding error accumulating).
But it looks to me as though your main error is in the iterative computation. You are modifying the rez variable before you use it in the computation of the new imz value. Your loop should look more like this:
while(rez * rez + imz * imz <= 4 && iter < MAX)
{
double rT = rez * rez - imz * imz + x;
imz = 2 * rez * imz + y;
rez = rT;
iter++;
}
Additionally to Peters answer, you should use a color palette instead of drawing just black and white pixels.
Create a array of colors, like this: (very simple example)
Color[] colors = new Colors[768];
for (int i=0; i<256; i++) {
colors[i ]=Color.FromArgb( i, 0, 0);
colors[i+256]=Color.FromArgb(255-i, i, 0);
colors[i+512]=Color.FromArgb(0 , 255-i, i);
}
Then use the iter value to pull a color and draw it:
int index=(int)((double)iter/MAX*767);
p.Color c = colors[index];
g.DrawRectangle(p, i, j, 1, 1);
Replace the entire if (iter == MAX) ... else ... statement with this last step.