Finding Coordinates of Line-Line Intersection in C# - c#

to start with I made a simple code that checks if 2 lines collide based on 4 points that are given by their x and y coordinates. It checks if the angle (variable k in my code) of both lines is the same, in that case they are parallel, otherwise they collide. The angle (k) was calculated based on the math equasion Click here [k = (y2-y1)/(x2-x1)]. Now I am not sure how to get the point they are colliding in. I would appreciate it very much if you could help me. Thank you in advance.
My Code: (method I call to calculate angle)
static void MetodaTrazenjaPresjeka(Duzina d1, Duzina d2)
{
int k11 = d1.Krajy - d1.Pocy; //y2-y1 - first line
int k12 = d1.Krajx - d1.Pocx; //x2-x1 - first line
double k1 = (double)k11 / k12; //angle of the first line
int k21 = d2.Krajy - d2.Pocy; //y2-y1 - second line
int k22 = d2.Krajx - d2.Pocx; //x2-x1 - second line
double k2 = (double)k21 / k22; //angle of the second line
if (k1 == k2)
{
//they are parallel
Console.WriteLine("MOJA METODA:");
Console.WriteLine("-----------------------------------");
Console.Write("Pravci zadani tockama su paralelni!");
}
else
{
//lines are colliding
Console.WriteLine("MOJA METODA:");
Console.WriteLine("-----------------------------------");
Console.Write("Pravci zadani tockama se sijeku!");
}
}
Code in class Duzina:
class Duzina
{
private int pocx, pocy, krajx, krajy;
//read/write attribute for the x coordinate of the first point
public int Pocx
{
get { return pocx; }
set { pocx = value; }
}
//read/write attribute for the y coordinate of the first point
public int Pocy
{
get { return pocy; }
set { pocy = value; }
}
//read/write attribute for the x coordinate of the second point
public int Krajx
{
get { return krajx; }
set { krajx = value; }
}
//read/write attribute for the y coordinate of the second point
public int Krajy
{
get { return krajy; }
set { krajy = value; }
}
//method that will print out coordinates of the given points
public void Ispis()
{
Console.Write("Pocetna tocka: ({0},{1})",Pocx,Pocy);
Console.Write("Krajnja tocka: ({0},{1})", Krajx, Krajy);
}
}

line equation: y = m * x + b
1) m_d1 = (d1.y2 - d1.y1) / (d1.x2 - d1.x1)
b_d1 = d1.y1 - m_d1 * d1.x1
(same for m_d2 and b_d2)
2) intersect.y = m_d1 * intersect.x + b_d1
intersect.y = m_d2 * intersect.x + b_d2
3) m_d1 * intersect.x + b_d1 = m_d2 * intersect.x + b_d2
4) intersect.x = (b_d2 - b_d1) / (m_d1 - m_d2)
now plug intersect.x that was obtained from 4) back into either equation in 2) to get intersection.y

Related

How to add conditional inside Linq Aggregate in C#?

I'm trying Linq over Imperative style, but I can't convert this conditional inside Aggregate to Linq.
Consider two following examples.
Simple example:
public enum Color {
Red, // Red score = 10
Yellow, // Yellow score = 5
Green, // Green score = 2
}
//Populate our sample list
public List<Color> Colors = new List<Color> {Red, Green, Green, Yellow};
//I need help on this one
public float Score => Colors.Aggregate(0.0f, (total, next) =>
{
//How to properly use conditional inside Aggregate?
if (next == Color.Red) {
return total + 10.0f;
} else if (next == Color.Yellow) {
return total + 5.0f;
} else if (next == Color.Green) {
return total + 2.0f;
}
//edit: forgot the default
return total;
}
Log(Score); //19
Edit: I have tried moving the conditional to Select, but then it will just move the problem, Which is how to add conditional inside Linq Select?
public float Score => Colors.Select(x =>
{
// The problem still happening
if (x == Color.Red) {
return 10.0f;
} else if (x == Color.Yellow) {
return 5.0f;
} else if (x == Color.Green) {
return 2.0f;
}
return 0.0f;
}
.Aggregate(0.0f, (total, next) => total + next);
And here is the complex example, basically it's just a stat modifier for a game,
// This is a Game Status Modifier, for example: "Strength 30 + 10%"
public enum StatModType
{
Flat = 100, // Flat addition to Stat
PercentAdd = 200, // Percent addition to Stat
... // many other type of addition
}
private float _baseValue = 30.0f;
public List<StatModifier> StatModifiers = new List<StatModifier>
{...} //dummy data
public float Value => StatModifiers.Aggregate(_baseValue, (finalValue, mod) =>
{
//I need help on this one
if (mod.Type == StatModType.Flat)
return finalValue + mod.Value;
else if (mod.Type == StatModType.PercentAdd)
// When we encounter a "PercentAdd" modifier
return finalValue + finalValue * mod.Value;
else if (mod.Type == ...)
//and continues below everytime I add more modifier types..
}
Log(Value); // Strength = 33;
Edit: I'll just post (Credit: https://forum.unity.com/threads/tutorial-character-stats-aka-attributes-system.504095/) the imperative code in case someone needs it, I also have a hard time reading this one:
private float CalculateFinalValue()
{
float finalValue = BaseValue;
float sumPercentAdd = 0; // This will hold the sum of our "PercentAdd" modifiers
for (int i = 0; i < statModifiers.Count; i++)
{
StatModifier mod = statModifiers[i];
if (mod.Type == StatModType.Flat)
{
finalValue += mod.Value;
}
else if (mod.Type == StatModType.PercentAdd) // When we encounter a "PercentAdd" modifier
{
sumPercentAdd += mod.Value; // Start adding together all modifiers of this type
// If we're at the end of the list OR the next modifer isn't of this type
if (i + 1 >= statModifiers.Count || statModifiers[i + 1].Type != StatModType.PercentAdd)
{
finalValue *= 1 + sumPercentAdd; // Multiply the sum with the "finalValue", like we do for "PercentMult" modifiers
sumPercentAdd = 0; // Reset the sum back to 0
}
}
else if (mod.Type == StatModType.PercentMult) // Percent renamed to PercentMult
{
finalValue *= 1 + mod.Value;
}
}
return (float)Math.Round(finalValue, 4);
}
How can I add conditional inside Aggregate / Reduce / Scan function?
I suggest extracting model in both cases i.e.
Simple Example:
private static Dictionary<Color, float> s_ColorScores = new Dictionary<Color, float>() {
{Color.Red, 10.0f},
{Color.Yellow, 5.0f},
{Color.Green, 2.0f},
};
...
float Score = Colors
.Sum(color => s_ColorScores[color]);
Complex Example:
private static Dictionary<StatModType, Func<float, float, float>> s_Modifications = new
Dictionary<StatModType, Func<float, float, float>> {
{StatModType.Flat, (prior, value) => prior + value},
{StatModType.PercentAdd, (prior, value) => prior + prior * value},
//TODO: add modification rules here
};
public float Value => StatModifiers
.Aggregate(_baseValue, (prior, mod) => s_Modifications[mod.Type](prior, mod.Value));
So you are going to have game's model (s_ColorScores, s_Modifications...) with rules, settings, balances etc. (which you will probably want to tune, may be Color.Yellow score of 6.0f is a better choice) separated from simple business logics.
Assuming that the behaviors associated to the enum types are static and not dynamic, based on this MSDocs article another approach would be to use enumeration classes instead of enum types. To simplify this, you could use the SmartEnum package.
Using this lib and approach, your use cases turn into:
Simple Example:
public sealed class Color: SmartEnum<Color>
{
public static readonly Color Red = new Color (nameof(Red), 1, 10.0f);
public static readonly Color Yellow = new Color (nameof(Yellow), 2, 20.0f);
public static readonly Color Green = new Color (nameof(Green), 3, 30.0f);
private Color(string name, int value, double score)
: base(name, value)
{
this.Score = score;
}
public float Score {get;}
}
float TotalScore = Colors
.Sum(color => color.Score);
Complex Example:
public sealed class StatMod: SmartEnum<StatMod>
{
public static readonly StatMod FlatAdd = new StatMod(nameof(FlatAdd), 200, (prev, val)=>prev+val);
public static readonly StatMod PercentAdd = new StatMod(nameof(PercentAdd), 300, (prev,val)=>prior + prior * value);
private StatMod(string name, int value, Func<float, float, float> reduce) : base(name, value)
{
this.Reduce = reduce;
}
public Func<float, float, float> Reduce {get;}
}
public float Value => StatModifiers
.Aggregate(_baseValue, (prior, mod) => mod.Reduce(prev, mod.Value));

C# custom sort by distance from a point

I am trying to sort a list using IComparer there are about 20,000 items in my list. The first approximately 100 and last 100 items are sorted but the center is not. I am not sure what I am doing wrong. Attached is the parts of the code that does the sort.
class myclass:me
{
private void mysort()
{
// Sort the data
DistComparer dc = new DistComparer();
st.Sort(dc);
}
}
class DistComparer : IComparer<Tower>
{
public int Compare(st x, st y)
{
double dist1 = getDistance(new PointF(45.0f, -80f), new PointF(x.Lat, x.Long));
double dist2 = getDistance(new PointF(45.0f, -80f), new PointF(y.Lat, y.Long));
if (dist1 > dist2)
return 1;
else if (dist1 == dist2)
return 0;
else
return -1;
}
private static double getDistance(PointF pt1, PointF pt2)
{
return Math.Sqrt(Math.Pow((pt1.X - pt2.X), 2) + Math.Pow((pt1.Y - pt2.Y), 2));
}
}
}

Towers of Hanoi: Moving Rings from Peg to Peg

Expanding on my previous post, I am still writing Towers of Hanoi. After having a wonderful solution explained of how to draw the rings on the pegs, I still have one question that I have been fiddling with for quite awhile now.
Here is my PegClass:
namespace Towers_Of_Hanoi
{
class PegClass
{
private int pegheight;
private int y = 3;
int[] rings = new int[0];
public PegClass()
{
//this is the default constructor
}
public PegClass(int height)
{
pegheight = height;
}
// other user defined functions
public void AddRing(int size)
{
Array.Resize (ref rings, rings.Length + 2);
rings[rings.Length - 1] = size;
}
public void DrawPeg(int x, int numberOfRings = 0)
{
for (int i = pegheight; i >= 1; i--)
{
string halfRing = new string (' ', i);
if (numberOfRings > 0)
{
if (i <= numberOfRings)
halfRing = new string ('-', numberOfRings - i + 1);
}
Console.SetCursorPosition(x - halfRing.Length * 2 + i + (halfRing.Contains("-") ? (-i + halfRing.Length) : 0), y);
Console.WriteLine(halfRing + "|" + halfRing);
y++;
}
if (x < 7) {
x = 7;
}
Console.SetCursorPosition (x - 7, y); //print the base of the peg
Console.WriteLine("----------------");
}
}
}
And here is my main method.
namespace Tower_of_hanoi
{
class Program
{
static void Main(string[] args)
{
PegClass myPeg = new PegClass(8);
PegClass myPeg2 = new PegClass(8);
PegClass myPeg3 = new PegClass(8);
DrawBoard(myPeg, myPeg2, myPeg3);
Console.WriteLine ("\t\t\nWelcome to kTowers!");
while (true)
{
string input = "\nWhat peg do you want to move to commander?";
Console.WriteLine (input);
if (input == "2")
{
myPeg.DrawPeg (2);
}
Console.ReadLine ();
}
}
public static void DrawBoard(PegClass peg1,PegClass peg2,PegClass peg3)
{
Console.Clear();
peg1.DrawPeg(20,1);
peg2.DrawPeg(40,2);
peg3.DrawPeg(60,4);
}
}
}
This is the current output:
| | |
| | |
| | |
| | |
| | -|-
| | --|--
| -|- ---|---
-|- --|-- ----|----
---------------- ---------------- ----------------
My question remains, how does one move the '-' characters from peg to peg when asked for a prompt. I've tried tweaking it for hours and still couldn't figure it out.
Thank you in advance, youmeoutside
You have manifested the rings as just "how many rings are on this peg" but that won't be enough.
For instance, if you have 8 rings you will represent one ring with width 1, one with width 2, one with 3, etc. up to one with 8.
In your image you have 3 rings with width of 1 (the top one on each peg), 2 with width 2 (the second ring on the two pegs that have multiple rings), and so on. This is incorrect and the reason for why your code does this is that it have no notion of "how wide should this particular ring be", instead it draws the top ring with width 1, the one below it with width 2, etc.
Instead here is a very simple set of objects to represent the rings and pegs and the operation to move from one to the other:
public void MoveRing(Peg fromPeg, Peg toPeg)
{
toPeg.Push(fromPeg.Pop());
}
public class Peg : Stack<Ring>
{
}
public struct Ring
{
public int Width { get; }
public Ring(int width) { Width = width; }
}
To create 3 pegs and stack 8 rings on the first peg you could use this code:
const int pegCount = 3;
const int ringCount = 8;
var pegs = Enumerable.Range(1, pegCount).Select(_ => new Peg()).ToList();
foreach (var ring in Enumerable.Range(1, ringCount).Select(width => new Ring(ringCount + 1 - width)))
pegs[0].Push(ring);
To draw them I took the liberty of fleshing out a LINQPad program that draws them to demonstrate but you could easily adapt this to the console code you have now:
void Main()
{
const int pegCount = 3;
const int ringCount = 8;
var pegs = Enumerable.Range(1, pegCount).Select(_ => new Peg()).ToList();
foreach (var ring in Enumerable.Range(1, ringCount).Select(width => new Ring(ringCount + 1 - width)))
pegs[0].Push(ring);
DrawPegs(pegs);
MoveRing(pegs[0], pegs[1]);
DrawPegs(pegs);
}
public void MoveRing(Peg fromPeg, Peg toPeg)
{
toPeg.Push(fromPeg.Pop());
}
public class Peg : Stack<Ring>
{
}
public struct Ring
{
public int Width { get; }
public Ring(int width) { Width = width; }
}
public void DrawPegs(IEnumerable<Peg> pegs)
{
var bitmaps = pegs.Select(peg => DrawPeg(peg));
Util.HorizontalRun(true, bitmaps).Dump();
}
public Bitmap DrawPeg(Peg peg)
{
const int width = 200;
const int height = 300;
const int pegWidth = 6;
const int ringHeight = 20;
const int ringWidthFactor = 10;
const int ringGapHeight = 3;
var result = new Bitmap(width, height);
using (var g = Graphics.FromImage(result))
{
g.Clear(Color.White);
g.FillRectangle(Brushes.Black, width / 2 - pegWidth/2, 0, pegWidth, height);
int y = height;
foreach (var ring in peg.Reverse())
{
y -= ringHeight;
g.FillRectangle(Brushes.Blue, width / 2 - ring.Width * ringWidthFactor, y, 2 * ring.Width * ringWidthFactor, ringHeight);
y -= ringGapHeight;
}
}
return result;
}
The output:

Alglib Data fitting with minlmoptimize does not minimize the results. Full c# included

I'm having trouble implementing the lm optimizer in the alglib library. I'm not sure why the parameters are hardly changing at all while still receiving an exit code of 4. I have been unable to determine what i am doing wrong with the documentation for alglib. Below is the full source I am running:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
namespace FBkineticsFitter
{
class Program
{
public static int Main(string[] args)
{
/*
* This code finds the parameters ka, kd, and Bmax from the minimization of the residuals using "V" mode of the Levenberg-Marquardt optimizer (alglib library).
* This optimizer is used because the equation is non-linear and this particular version of the optimizer does not require the ab inito calculation of partial
* derivatives, a jacobian matrix, or other parameter-space definitions, so it's implementation is simple.
*
* The equations being solved represent a model of a protein-protein interaction where protein in solution is interacting with immobilized protein on a sensor
* in a 1:1 stoichiometery. Mass transport limit is not taken into account. The detials of this equation are described in:
* R.B.M. Schasfoort and Anna J. Tudos Handbook of Surface Plasmon Resonance, 2008, Chapter 5, ISBN: 978-0-85404-267-8
*
* Y=((ka*Cpro*Bmax)/(ka*Cpro+kd))*(1-exp(-1*X*(ka*Cpro+kd))) ; this equation describes the association phase
*
* Y=Req*exp(-1*X*kd) ; this equation describes the dissociation phase
*
* The data are fit globally such that Bmax and Req parameters are linked and kd parameters are linked during simultaneous optimization for the most robust fit
*
* Y= signal
* X= time
* ka= association constant
* kd= dissociation constant
* Bmax= maximum binding capacity at equilibrium
* Req=(Cpro/(Cpro+kobs))*Bmax :. in this case Req=Bmax because Cpro=0 during the dissociation step
* Cpro= concentration of protein in solution
*
* additional calculations:
* kobs=ka*Cpro
* kD=kd/ka
*/
GetRawDataXY(#"C:\Results.txt");
double epsg = .0000001;
double epsf = 0;
double epsx = 0;
int maxits = 0;
alglib.minlmstate state;
alglib.minlmreport rep;
alglib.minlmcreatev(2, GlobalVariables.param, 0.0001, out state);
alglib.minlmsetcond(state, epsg, epsf, epsx, maxits);
alglib.minlmoptimize(state, Calc_residuals, null, null);
alglib.minlmresults(state, out GlobalVariables.param, out rep);
System.Console.WriteLine("{0}", rep.terminationtype); ////1=relative function improvement is no more than EpsF. 2=relative step is no more than EpsX. 4=gradient norm is no more than EpsG. 5=MaxIts steps was taken. 7=stopping conditions are too stringent,further improvement is impossible, we return best X found so far. 8= terminated by user
System.Console.WriteLine("{0}", alglib.ap.format(GlobalVariables.param, 20));
System.Console.ReadLine();
return 0;
}
public static void Calc_residuals(double[] param, double[] fi, object obj)
{
/*calculate the difference of the model and the raw data at each X (I.E. residuals)
* the sum of the square of the residuals is returned to the optimized function to be minimized*/
fi[0] = 0;
fi[1] = 0;
for (int i = 0; i < GlobalVariables.rawXYdata[0].Count();i++ )
{
if (GlobalVariables.rawXYdata[1][i] <= GlobalVariables.breakpoint)
{
fi[0] += System.Math.Pow((kaEQN(GlobalVariables.rawXYdata[0][i]) - GlobalVariables.rawXYdata[1][i]), 2);
}
else
{
fi[1] += System.Math.Pow((kdEQN(GlobalVariables.rawXYdata[0][i]) - GlobalVariables.rawXYdata[1][i]), 2);
}
}
}
public static double kdEQN(double x)
{
/*Calculate kd Y value based on the incremented parameters*/
return GlobalVariables.param[2] * Math.Exp(-1 * x * GlobalVariables.param[1]);
}
public static double kaEQN(double x)
{
/*Calculate ka Y value based on the incremented parameters*/
return ((GlobalVariables.param[0] * GlobalVariables.Cpro * GlobalVariables.param[2]) / (GlobalVariables.param[0] * GlobalVariables.Cpro + GlobalVariables.param[1])) * (1 - Math.Exp(-1 * x * (GlobalVariables.param[0] * GlobalVariables.Cpro + GlobalVariables.param[1])));
}
public static void GetRawDataXY(string filename)
{
/*Read in Raw data From tab delim txt*/
string[] elements = { "x", "y" };
int count = 0;
GlobalVariables.rawXYdata[0] = new double[1798];
GlobalVariables.rawXYdata[1] = new double[1798];
using (StreamReader sr = new StreamReader(filename))
{
while (sr.Peek() >= 0)
{
elements = sr.ReadLine().Split('\t');
GlobalVariables.rawXYdata[0][count] = Convert.ToDouble(elements[0]);
GlobalVariables.rawXYdata[1][count] = Convert.ToDouble(elements[1]);
count++;
}
}
}
public class GlobalVariables
{
public static double[] param = new double[] { 1, .02, 0.13 }; ////ka,kd,Bmax these are initial guesses for the algorithm
public static double[][] rawXYdata = new double[2][];
public static double Cpro = 100E-9;
public static double kD = 0;
public static double breakpoint = 180;
}
}
}
According to Sergey Bochkanova The issue is the following:
"You should use param[] array which is provided to you by optimizer. It creates its internal copy of your param, and updates this copy - not your param array.
From the optimizer point of view, it has function which never changes when it changes its internal copy of param. So, it terminates right after first iteration."
Here is the updated and working example code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
namespace FBkineticsFitter
{
class Program
{
public static int Main(string[] args)
{
/*
* This code finds the parameters ka, kd, and Bmax from the minimization of the residuals using "V" mode of the Levenberg-Marquardt optimizer (alglib library).
* This optimizer is used because the equation is non-linear and this particular version of the optimizer does not require the ab inito calculation of partial
* derivatives, a jacobian matrix, or other parameter-space definitions, so it's implementation is simple.
*
* The equations being solved represent a model of a protein-protein interaction where protein in solution is interacting with immobilized protein on a sensor
* in a 1:1 stoichiometery. Mass transport limit is not taken into account. The detials of this equation are described in:
* R.B.M. Schasfoort and Anna J. Tudos Handbook of Surface Plasmon Resonance, 2008, Chapter 5, ISBN: 978-0-85404-267-8
*
* Y=((Cpro*Rmax)/(Cpro+kd))*(1-exp(-1*X*(ka*Cpro+kd))) ; this equation describes the association phase
*
* Y=Req*exp(-1*X*kd)+NS ; this equation describes the dissociation phase
*
* According to ForteBio's Application Notes #14 the amplitudes of the data can be correctly accounted for by modifying the above equations as follows:
*
* Y=(Rmax*(1/(1+(kd/(ka*Cpro))))*(1-exp(((-1*Cpro)+kd)*X)) ; this equation describes the association phase
*
* Y=Y0*(exp(-1*kd*(X-X0))) ; this equation describes the dissociation phase
*
*
*
* The data are fit simultaneously such that all fitting parameters are linked during optimization for the most robust fit
*
* Y= signal
* X= time
* ka= association constant [fitting parameter 0]
* kd= dissociation constant [fitting parameter 1]
* Rmax= maximum binding capacity at equilibrium [fitting parameter 2]
* KD=kd/ka
* kobs=ka*Cpro+kd
* Req=(Cpro/(Cpro+KD))*Rmax
* Cpro= concentration of protein in solution
* NS= non-specific binding at time=infinity (constant correction for end point of fit) [this is taken into account in the amplitude corrected formula: Y0=Ylast]
* Y0= the initial value of Y for the first point of the dissociation curve (I.E. the last point of the association phase)
* X0= the initial value of X for the first point of the dissociation phase
*
*/
GetRawDataXY(#"C:\Results.txt");
double epsg = .00001;
double epsf = 0;
double epsx = 0;
int maxits = 10000;
alglib.minlmstate state;
alglib.minlmreport rep;
double[] param = new double[] { 1000000, .0100, 0.20};////ka,kd,Rmax these are initial guesses for the algorithm and should be mid range for the expected data., The last parameter Rmax should be guessed as the maximum Y-value of Ka
double[] scaling= new double[] { 1E6,1,1};
alglib.minlmcreatev(2, param, 0.001, out state);
alglib.minlmsetcond(state, epsg, epsf, epsx, maxits);
alglib.minlmsetgradientcheck(state, 1);
alglib.minlmsetscale(state, scaling);
alglib.minlmoptimize(state, Calc_residuals, null, V.rawXYdata);
alglib.minlmresults(state, out param, out rep);
System.Console.WriteLine("{0}", rep.terminationtype); ////1=relative function improvement is no more than EpsF. 2=relative step is no more than EpsX. 4=gradient norm is no more than EpsG. 5=MaxIts steps was taken. 7=stopping conditions are too stringent,further improvement is impossible, we return best X found so far. 8= terminated by user
System.Console.WriteLine("{0}", alglib.ap.format(param, 25));
System.Console.ReadLine();
return 0;
}
public static void Calc_residuals(double[] param, double[] fi, object obj)
{
/*calculate the difference of the model and the raw data at each X (I.E. residuals)
* the sum of the square of the residuals is returned to the optimized function to be minimized*/
CalcVariables(param);
fi[0] = 0;
fi[1] = 0;
for (int i = 0; i < V.rawXYdata[0].Count(); i++)
{
if (V.rawXYdata[0][i] <= V.breakpoint)
{
fi[0] += System.Math.Pow((kaEQN(V.rawXYdata[0][i], param) - V.rawXYdata[1][i]), 2);
}
else
{
if (!V.breakpointreached)
{
V.breakpointreached = true;
V.X_0 = V.rawXYdata[0][i];
V.Y_0 = V.rawXYdata[1][i];
}
fi[1] += System.Math.Pow((kdEQN(V.rawXYdata[0][i], param) - V.rawXYdata[1][i]), 2);
}
}
if (param[0] <= 0 || param[1] <=0 || param[2] <= 0)////Exponentiates the error if the parameters go negative to favor positive non-zero values
{
fi[0] = Math.Pow(fi[0], 2);
fi[1] = Math.Pow(fi[1], 2);
}
System.Console.WriteLine("{0}"+" "+V.Cpro+" -->"+fi[0], alglib.ap.format(param, 5));
Console.WriteLine((kdEQN(V.rawXYdata[0][114], param)));
}
public static double kdEQN(double X, double[] param)
{
/*Calculate kd Y value based on the incremented parameters*/
return (V.Rmax * (1 / (1 + (V.kd / (V.ka * V.Cpro)))) * (1 - Math.Exp((-1 * V.ka * V.Cpro) * V.X_0))) * Math.Exp((-1 * V.kd) * (X - V.X_0));
}
public static double kaEQN(double X, double[] param)
{
/*Calculate ka Y value based on the incremented parameters*/
return ((V.Cpro * V.Rmax) / (V.Cpro + V.kd)) * (1 - Math.Exp(-1 * X * ((V.ka * V.Cpro) + V.kd)));
}
public static void GetRawDataXY(string filename)
{
/*Read in Raw data From tab delim txt*/
string[] elements = { "x", "y" };
int count = 0;
V.rawXYdata[0] = new double[226];
V.rawXYdata[1] = new double[226];
using (StreamReader sr = new StreamReader(filename))
{
while (sr.Peek() >= 0)
{
elements = sr.ReadLine().Split('\t');
V.rawXYdata[0][count] = Convert.ToDouble(elements[0]);
V.rawXYdata[1][count] = Convert.ToDouble(elements[1]);
count++;
}
}
}
public class V
{
/*Global Variables*/
public static double[][] rawXYdata = new double[2][];
public static double Cpro = 100E-9;
public static bool breakpointreached = false;
public static double X_0 = 0;
public static double Y_0 = 0;
public static double ka = 0;
public static double kd = 0;
public static double Rmax = 0;
public static double KD = 0;
public static double Kobs = 0;
public static double Req = 0;
public static double breakpoint = 180;
}
public static void CalcVariables(double[] param)
{
V.ka = param[0];
V.kd = param[1];
V.Rmax = param[2];
V.KD = param[1] / param[0];
V.Kobs = param[0] * V.Cpro + param[1];
V.Req = (V.Cpro / (V.Cpro + param[0] * V.Cpro + param[1])) * param[2];
}
}
}

C# Methods: Defined Parameter Default Value Issue

I am writing an app that requires the calculation of the Gamma function.
A code (part of a class) snippet is below:
namespace PB.Utilities.Math
{
// class definition
public class SpecialFunctions
{
// Private Fields
// Instance Constructor
public SpecialFunctions() {}
// Public Method for Gamma Function
// x = input value; x MUST BE > 0
// GammaLn = secondary output value equal to natural log of Gamma Function
public double Gamma(double x, out double GammaLn)
{
try
{
if (x <= 0) throw new System.ArgumentException("arg <= 0 in GammaFunction", "x");
}
catch
{
System.Console.WriteLine("argument <= 0 in GammaFunction");
System.Console.ReadKey();
}
double gammaln;
double _gamma = gamma(x, out gammaln);
GammaLn = gammaln;
return _gamma;
}
// private method for Gamma Function
private double gamma(double xx, out double gammaln)
{
// private constants
int j;
double x,tmp,y,ser;
const double k1 = 5.24218750000000000;
const double k2 = 0.999999999999997092;
const double k3 = 2.5066282746310005;
double[] cof = new double[14]
{
57.1562356658629235, -59.5979603554754912, 14.1360979747417471,
-0.491913816097620199, 0.339946499848118887e-4, 0.465236289270485756e-4,
-0.983744753048795646e-4, 0.158088703224912494e-3, -0.210264441724104883e-3,
0.217439618115212643e-3, -0.164318106536763890e-3, 0.844182239838527433e-4,
-0.261908384015814087e-4, 0.368991826595316234e-5
};
y = x = xx;
tmp = x + k1;
tmp = (x + 0.5) * System.Math.Log(tmp) - tmp;
ser = k2;
for (j = 0; j < 14; j++) ser += cof[j]/++y;
gammaln = tmp + System.Math.Log(k3*ser/x);
return System.Math.Exp(gammaln);
}
}
}
public class BSA
{
static void Main()
{
// Create an object of type PB.Utilities.Math.SpecialFunctions
PB.Utilities.Math.SpecialFunctions Function = new PB.Utilities.Math.SpecialFunctions();
// Call the public method GammaFunction.
double GammaLn1;
double GammaLn2;
double GammaLn3;
double g1 = Function.Gamma(3.5, out GammaLn1);
double g2 = Function.Gamma(1.5, out GammaLn2);
double g3 = Function.Gamma(1/7, out GammaLn3);
System.Console.WriteLine("g(7/2) = "+g1);
System.Console.WriteLine("g(3/2) = "+g2);
System.Console.WriteLine("g(1/7) = "+g3);
}
}
The issue is that at compilation, the parameter x in Gamma (even though x is being assigned the value 3.5 in the calling component) is assigned a value of 0 which triggers the exception. Can anyone please suggest how I can get around this? Thank you.
Seems to be 3.5 in my test cases. Are you sure you haven't excluded some information that might be the issue?
using System;
namespace Doubletesting
{
class Program
{
static void Main(string[] args)
{
double d = Doubletesting.TestDouble(3.5);
Console.WriteLine(d.ToString());
Console.ReadKey();
}
public static double TestDouble(double x)
{
double result;
result = x;
return result;
}
}
}
Result
3.5
UPDATED
The Error is caused by your Function.Gamma(1 / 7, out GammaLn3). This is because both 1 and 7 are INT and dividing (int)1 by (int)7 is zero. Try Function.Gamma(1f / 7f, out GammaLn3).

Categories

Resources