Getting runtime error, C# Converting Array to Int - c#

for some reason this will compile but it comes out with an error at the end and I can't figure out why. The first part of the code is to display a table from a text file which works correctly, the second part doesn't.
I don't think it even gets to the Console.WriteLine bit, which was a way of checking whether it did. Can anyone see why?
Thanks for any help you can give!
class Program
{
static void Main(string[] args)
{
List<float> inputList = new List<float>();
TextReader tr = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
String input = Convert.ToString(tr.ReadToEnd());
String[] items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (int i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
// Ask for two bits of data which are then stored in Longtitude, Latitude and Elevation
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
string point = Console.ReadLine();
string[] pointInput = point.Split(' ');
int pointNumber = Convert.ToInt16 (pointInput[0]);
int pointNumber2 = Convert.ToInt16 (pointInput[1]);
int Latitude = (Convert.ToInt16(items[pointNumber*3]));
int Longtitude = (Convert.ToInt16(items[(pointNumber*3)+1]));
int Elevation = (Convert.ToInt16(items[(pointNumber*3)+2]));
int Latitude2 = (Convert.ToInt16(items[pointNumber2 * 3]));
int Longtitude2 = (Convert.ToInt16(items[(pointNumber2 * 3) + 1]));
int Elevation2 = (Convert.ToInt16(items[(pointNumber2 * 3) + 2]));
Console.WriteLine("Latitude");
Console.WriteLine("Latitude2");

You are using decimal values, which cannot be converted into Int16. So use float.
Also, Outputting "Latitude" will write the variable's name, not its value.
I modified your code:
float Latitude = (float.Parse(items[pointNumber*3]));
float Longtitude = (float.Parse(items[(pointNumber*3)+1]));
float Elevation = (float.Parse(items[(pointNumber*3)+2]));
float Latitude2 = (float.Parse(items[pointNumber2 * 3]));
float Longtitude2 = (float.Parse(items[(pointNumber2 * 3) + 1]));
float Elevation2 = (float.Parse(items[(pointNumber2 * 3) + 2]));
Console.WriteLine(Latitude);
Console.WriteLine(Latitude2);

Your input strings are of floating values, not integers. You can parse to floats like this:
float Latitude = (Convert.ToSingle(items[pointNumber * 3]));
float Longtitude = (Convert.ToSingle(items[(pointNumber * 3) + 1]));
float Elevation = (Convert.ToSingle(items[(pointNumber * 3) + 2]));
float Latitude2 = (Convert.ToSingle(items[pointNumber2 * 3]));
float Longtitude2 = (Convert.ToSingle(items[(pointNumber2 * 3) + 1]));
float Elevation2 = (Convert.ToSingle(items[(pointNumber2 * 3) + 2]));

Related

Excel RATE function in .NET CORE

I tried to use RATE function in .NET CORE project.
There is a Visual Basic library I wanted to use but it does not work with .NET CORE.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.financial.rate?view=netframework-4.7.2
Are there any other ways to use it or should I calculate it explicitly? How? I can't find any explanation of this function.
According to #omajid comment I transform official VB code to C#.
This is all you need to use Rate method without dependency on Microsoft.VisualBasic.dll which is lacking this method in .NET CORE.
private double Rate(double NPer, double Pmt, double PV, double FV = 0, DueDate Due = DueDate.EndOfPeriod, double Guess = 0.1)
{
double dTemp;
double dRate0;
double dRate1;
double dY0;
double dY1;
int I;
// Check for error condition
if (NPer <= 0.0)
throw new ArgumentException("NPer must by greater than zero");
dRate0 = Guess;
dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due);
if (dY0 > 0)
dRate1 = (dRate0 / 2);
else
dRate1 = (dRate0 * 2);
dY1 = LEvalRate(dRate1, NPer, Pmt, PV, FV, Due);
for (I = 0; I <= 39; I++)
{
if (dY1 == dY0)
{
if (dRate1 > dRate0)
dRate0 = dRate0 - cnL_IT_STEP;
else
dRate0 = dRate0 - cnL_IT_STEP * (-1);
dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due);
if (dY1 == dY0)
throw new ArgumentException("Divide by zero");
}
dRate0 = dRate1 - (dRate1 - dRate0) * dY1 / (dY1 - dY0);
// Secant method of generating next approximation
dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due);
if (Math.Abs(dY0) < cnL_IT_EPSILON)
return dRate0;
dTemp = dY0;
dY0 = dY1;
dY1 = dTemp;
dTemp = dRate0;
dRate0 = dRate1;
dRate1 = dTemp;
}
throw new ArgumentException("Can not calculate rate");
}
private double LEvalRate(double Rate, double NPer, double Pmt, double PV, double dFv, DueDate Due)
{
double dTemp1;
double dTemp2;
double dTemp3;
if (Rate == 0.0)
return (PV + Pmt * NPer + dFv);
else
{
dTemp3 = Rate + 1.0;
// WARSI Using the exponent operator for pow(..) in C code of LEvalRate. Still got
// to make sure that they (pow and ^) are same for all conditions
dTemp1 = Math.Pow(dTemp3, NPer);
if (Due != 0)
dTemp2 = 1 + Rate;
else
dTemp2 = 1.0;
return (PV * dTemp1 + Pmt * dTemp2 * (dTemp1 - 1) / Rate + dFv);
}
}
private const double cnL_IT_STEP = 0.00001;
private const double cnL_IT_EPSILON = 0.0000001;
enum DueDate
{
EndOfPeriod = 0,
BegOfPeriod = 1
}

Dealing with imprecise, jittery gps signal

My goal is to use GPS to measure the distance that I moved with my phone. My problem is, that the results are imprecise. I've used the following code to calculate the distance:
public double getDistance(GeoCoordinate p1, GeoCoordinate p2)
{
double d = p1.Latitude * 0.017453292519943295;
double num3 = p1.Longitude * 0.017453292519943295;
double num4 = p2.Latitude * 0.017453292519943295;
double num5 = p2.Longitude * 0.017453292519943295;
double num6 = num5 - num3;
double num7 = num4 - d;
double num8 = Math.Pow(Math.Sin(num7 / 2.0), 2.0) + ((Math.Cos(d) * Math.Cos(num4)) * Math.Pow(Math.Sin(num6 / 2.0), 2.0));
double num9 = 2.0 * Math.Atan2(Math.Sqrt(num8), Math.Sqrt(1.0 - num8));
return (6376500.0 * num9);
}
This is my OnLocationChanged implementation:
bool begin = true;
public void OnLocationChanged(Location location)
{
_aktuellerOrt = location;
//aktuellerOrt.Speed is always 0, so I cannot use that.
if (_aktuellerOrt == null)
{
//message
}
else
{
if (_aktuellerOrt.Accuracy > 70) //I found values around 130 to be more or less good
{
_locationText.Text = String.Format("{0}, {1}", _aktuellerOrt.Latitude, _aktuellerOrt.Longitude);
GeoJetzt = new GeoCoordinate();
GeoJetzt.Latitude = _aktuellerOrt.Latitude;
GeoJetzt.Longitude = _aktuellerOrt.Longitude;
if (beginn)
{
GeoVorher = new GeoCoordinate();
GeoVorher.Latitude = _aktuellerOrt.Latitude;
GeoVorher.Longitude = _aktuellerOrt.Longitude;
beginn = false;
}
else
{
double abstand = getDistance(GeoVorher, GeoJetzt);
weg += abstand;
if (weg >= 1)
_distanzText.Text = weg + " kilometers";
else
_distanzText.Text = (weg * 1000) + " meters";
_distanzText.Text += " (" + abstand + ", " + _aktuellerOrt.Accuracy + ")";
GeoVorher = new GeoCoordinate();
GeoVorher.Latitude = _aktuellerOrt.Latitude;
GeoVorher.Longitude = _aktuellerOrt.Longitude;
}
}
else
_locationText.Text = "Too coarse, now " + _aktuellerOrt.Accuracy + ".";
}
}
The problem is, I get values for abstand within the kilometer range while not moving the phone.
What are best practices for imprecise signals? My goal is to measure the distance while jogging or running, so 10 - 16 km/h.

C# to mimic Excel SLOPE function

I'm trying to calculate the slope of two data lists. You can easily calculate this in EXCEL using the SLOPE function. =SLOPE(A1:A100, B1:B100). I'm trying to mimic this function in C# WinForm. Here is my code, it can calculate something, but not the correct number that you would get from the Excel function. Please help me find the error here. Thanks so much!
private double Getslope(List<double> ProductGrossExcessReturnOverRFR, List<double> primaryIndexExcessReturnOverRFR, int months, int go_back = 0)
{
double slope = 0;
double sumx = 0, sumy = 0, sumxy = 0, sumx2 = 0;
for (int i = ProductGrossExcessReturnOverRFR.Count - 1 - go_back; i > ProductGrossExcessReturnOverRFR.Count - (1 + months + go_back); i--)
{
sumxy += ProductGrossExcessReturnOverRFR[i] * primaryIndexExcessReturnOverRFR[i];
sumx += ProductGrossExcessReturnOverRFR[i];
sumy += primaryIndexExcessReturnOverRFR[i];
sumx2 += ProductGrossExcessReturnOverRFR[i] * ProductGrossExcessReturnOverRFR[i];
}
return slope = 1 / (((sumxy - sumx * sumy / months) / (sumx2 - sumx * sumx / months)));
}
Test data:
{1.085231224, 2.335034309, 0.346667278} and
{3.185231224,3.705034309 , -0.883332722} should have slope of 0.3373 if you calculate in Excel using =SLOPE function. But my code produces 0.47 somehow...
I think your formula is wrong
According to the Excel documentation the formula for SLOPE is
Note also that the first argument to the function is the the y values.
It's unclear how goback and months apply, but it looks like this might work:
private double Getslope(List<double> ProductGrossExcessReturnOverRFR,
List<double> primaryIndexExcessReturnOverRFR,
int months,
int go_back = 0)
{
// calc # of items to skip
int skip = ProductGrossExcessReturnOverRFR.Count - go_back - months;
// get list of x's and y's
var ys = ProductGrossExcessReturnOverRFR.Skip(skip).Take(months);
var xs = primaryIndexExcessReturnOverRFR.Skip(skip).Take(months);
// "zip" xs and ys to make the sum of products easier
var xys = Enumerable.Zip(xs,ys, (x, y) => new {x = x, y = y});
double xbar = xs.Average();
double ybar = ys.Average();
double slope = xys.Sum(xy => (xy.x - xbar) * (xy.y - ybar)) / xs.Sum(x => (x - xbar)*(x - xbar));
return slope;
}

Restart program from a certain line with an if statement?

could anyone help me restart my program from line 46 if the user enters 1 (just after the comment where it states that the next code is going to ask the user for 2 inputs) and if the user enters -1 end it. I cannot think how to do it. I'm new to C# any help you could give would be great!
class Program
{
static void Main(string[] args)
{
//Displays data in correct Format
List<float> inputList = new List<float>();
TextReader tr = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
String input = Convert.ToString(tr.ReadToEnd());
String[] items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (int i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
// Ask for two inputs from the user which is then converted into 6 floats and transfered in class Coordinates
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
string point = Console.ReadLine();
string[] pointInput = point.Split(' ');
int pointNumber = Convert.ToInt16(pointInput[0]);
int pointNumber2 = Convert.ToInt16(pointInput[1]);
Coordinates distance = new Coordinates();
distance.latitude = (Convert.ToDouble(items[pointNumber * 3]));
distance.longtitude = (Convert.ToDouble(items[(pointNumber * 3) + 1]));
distance.elevation = (Convert.ToDouble(items[(pointNumber * 3) + 2]));
distance.latitude2 = (Convert.ToDouble(items[pointNumber2 * 3]));
distance.longtitude2 = (Convert.ToDouble(items[(pointNumber2 * 3) + 1]));
distance.elevation2 = (Convert.ToDouble(items[(pointNumber2 * 3) + 2]));
//Calculate the distance between two points
const double PIx = 3.141592653589793;
const double RADIO = 6371;
double dlat = ((distance.latitude2) * (PIx / 180)) - ((distance.latitude) * (PIx / 180));
double dlon = ((distance.longtitude2) * (PIx / 180)) - ((distance.longtitude) * (PIx / 180));
double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos((distance.latitude) * (PIx / 180)) * Math.Cos((distance.latitude2) * (PIx / 180)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
double ultimateDistance = (angle * RADIO);
Console.WriteLine("The distance between your two points is...");
Console.WriteLine(ultimateDistance);
//Repeat the program if the user enters 1, end the program if the user enters -1
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
Console.ReadLine();
if (Convert.ToInt16(Console.ReadLine()) == 1);
{
//here is where I need it to repeat
}
bool exit = false;
do
{
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
...
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
string input;
do
{
input = Console.ReadLine().Trim();
}
while (input != "1" && input != "-1");
if (input == -1) exit = true;
}
while (!exit);
But you would do much better to think about pushing logic into methods and functions such that you program is built up of much smaller building blocks.
You should be aiming towards something like this:
bool exit = false;
do
{
Point[] points = ReadCoordinates();
Whatever result = CalculateWhatever();
DisplayResults(results);
exit = ShouldExit();
}
while (!exit);
This makes the outer loop of your program self documenting and the methods self explanatory.
if (Convert.ToInt16(Console.ReadLine()) == 1);
{
Main(args)
}
That's quite an odd thing to do.
Have you looked into the while loop?
You could make a method of the above structure and loop it, while userinput equals 1
if it equals -1, call the following statement
Application.Exit()
Can use Goto to make the program loop on user input.
public static void Main(string[] args)
{
RestartApplication:
//// Displays data in correct Format
TextReader textReader = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
var input = Convert.ToString(textReader.ReadToEnd());
var items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (var i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
//// Ask for two inputs from the user which is then converted into 6 floats and transferred in class Coordinates
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
var point = Console.ReadLine();
string[] pointInput;
if (point != null)
{
pointInput = point.Split(' ');
}
else
{
goto RestartApplication;
}
var pointNumber = Convert.ToInt16(pointInput[0]);
var pointNumber2 = Convert.ToInt16(pointInput[1]);
var distance = new Coordinates
{
Latitude = Convert.ToDouble(items[pointNumber * 3]),
Longtitude = Convert.ToDouble(items[(pointNumber * 3) + 1]),
Elevation = Convert.ToDouble(items[(pointNumber * 3) + 2]),
Latitude2 = Convert.ToDouble(items[pointNumber2 * 3]),
Longtitude2 = Convert.ToDouble(items[(pointNumber2 * 3) + 1]),
Elevation2 = Convert.ToDouble(items[(pointNumber2 * 3) + 2])
};
//// Calculate the distance between two points
const double PIx = 3.141592653589793;
const double Radio = 6371;
var dlat = (distance.Latitude2 * (PIx / 180)) - (distance.Latitude * (PIx / 180));
var dlon = (distance.Longtitude2 * (PIx / 180)) - (distance.Longtitude * (PIx / 180));
var a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(distance.Latitude * (PIx / 180)) * Math.Cos(distance.Latitude2 * (PIx / 180)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
var angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
var ultimateDistance = angle * Radio;
Console.WriteLine("The distance between your two points is...");
Console.WriteLine(ultimateDistance);
//// Repeat the program if the user enters 1, end the program if the user enters -1
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
var userInput = Console.ReadLine();
if (Convert.ToInt16(userInput) == 1)
{
//// Here is where the application will repeat.
goto RestartApplication;
}
}
also did a bit of code formatting. Hope it helps.
You could do that with goto, be aware however that this is considered bad practice.
static void Main(string[] args)
{
...
MyLabel:
...
if (Convert.ToInt16(Console.ReadLine()) == 1);
{
//here is where I need it to repeat
goto MyLabel;
}

Generate a random number in a Gaussian Range?

I want to use a random number generator that creates random numbers in a gaussian range where I can define the median by myself. I already asked a similar question here and now I'm using this code:
class RandomGaussian
{
private static Random random = new Random();
private static bool haveNextNextGaussian;
private static double nextNextGaussian;
public static double gaussianInRange(double from, double mean, double to)
{
if (!(from < mean && mean < to))
throw new ArgumentOutOfRangeException();
int p = Convert.ToInt32(random.NextDouble() * 100);
double retval;
if (p < (mean * Math.Abs(from - to)))
{
double interval1 = (NextGaussian() * (mean - from));
retval = from + (float)(interval1);
}
else
{
double interval2 = (NextGaussian() * (to - mean));
retval = mean + (float)(interval2);
}
while (retval < from || retval > to)
{
if (retval < from)
retval = (from - retval) + from;
if (retval > to)
retval = to - (retval - to);
}
return retval;
}
private static double NextGaussian()
{
if (haveNextNextGaussian)
{
haveNextNextGaussian = false;
return nextNextGaussian;
}
else
{
double v1, v2, s;
do
{
v1 = 2 * random.NextDouble() - 1;
v2 = 2 * random.NextDouble() - 1;
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = Math.Sqrt(-2 * Math.Log(s) / s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}
Then to verify the results I plotted them with gaussianInRange(0, 0.5, 1) for n=100000000
As one can see the median is really at 0.5 but there isn't really a curve visible. So what I'm doing wrong?
EDIT
What i want is something like this where I can set the highest probability by myself by passing a value.
The simplest way to draw normal deviates conditional on them being in a particular range is with rejection sampling:
do {
retval = NextGaussian() * stdev + mean;
} while (retval < from || to < retval);
The same sort of thing is used when you draw coordinates (v1, v2) in a circle in your unconditional normal generator.
Simply folding in values outside the range doesn't produce the same distribution.
Also, if you have a good implementation of the error function and its inverse, you can calculate the values directly using an inverse CDF. The CDF of a normal distribution is
F(retval) = (1 + erf((retval-mean) / (stdev*sqrt(2)))) / 2
The CDF of a censored distribution is
C(retval) = (F(retval) - F(from)) / (F(to) - F(from)), from ≤ x < to
To draw a random number using a CDF, you draw v from a uniform distribution on [0, 1] and solve C(retval) = v. This gives
double v = random.NextDouble();
double t1 = erf((from - mean) / (stdev*sqrt(2)));
t2 = erf((to - mean) / (stdev*sqrt(2)));
double retval = mean + stdev * sqrt(2) * erf_inv(t1*(1-v) + t2*v);
You can precalculate t1 and t2 for specific parameters. The advantage of this approach is that there is no rejection sampling, so you only need a single NextDouble() per draw. If the [from, to] interval is small this will be faster.
However, it sounds like you might want the binomial distribution instead.
I have similar methods in my Graph generator (had to modify it a bit):
Returns a random floating-point number using a generator function with a specific range:
private double NextFunctional(Func<double, double> func, double from, double to, double height, out double x)
{
double halfWidth = (to - from) / 2;
double distance = halfWidth + from;
x = this.rand.NextDouble() * 2 - 1;// -1 .. 1
double y = func(x);
x = halfWidth * x + distance;
y *= height;
return y;
}
Gaussian function:
private double Gauss(double x)
{
// Graph should look better with double-x scale.
x *= 2;
double σ = 1 / Math.Sqrt(2 * Math.PI);
double variance = Math.Pow(σ, 2);
double exp = -0.5 * Math.Pow(x, 2) / variance;
double y = 1 / Math.Sqrt(2 * Math.PI * variance) * Math.Pow(Math.E, exp);
return y;
}
A method that generates a graph using the random numbers:
private void PlotGraph(Graphics g, Pen p, double from, double to, double height)
{
for (int i = 0; i < 1000; i++)
{
double x;
double y = this.NextFunctional(this.Gauss, from, to, height, out x);
this.DrawPoint(g, p, x, y);
}
}
I would rather used a cosine function - it is much faster and pretty close to the gaussian function for your needs:
double x;
double y = this.NextFunctional(a => Math.Cos(a * Math.PI), from, to, height, out x);
The out double x parameter in the NextFunctional() method is there so you can easily test it on your graphs (I use an iterator in my method).

Categories