find roots of cubic polynomial - c#

I'm trying to find the roots of a cubic polynomial ax^3+bx^2+cx+d=0 using math.numerics. The package is great, but I'm struggling to get started with it. Please can someone explain how to find the roots, and a simple explanation on how to run the sample package from Github?
I've added a reference to the package
using MathNet.Numerics;
and this is what I've tried:
var roots = FindRoots.Cubic(d, c, b, a);
double root1=roots.item1;
double root2=roots.item2;
double root3=roots.item3;
but I get an error "The type 'Complex' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Numerics'". Adding using System.Numerics gives an error and doesn't solve the problem.
Any suggestions please?

If you're using Visual Studio, you need to right-click the References folder for your project in Solution Explorer, click Add Reference, and then select System.Numerics from the Assemblies > Framework list:
Because MathNet.Numerics.FindRoots.Cubic returns roots as complex numbers, you must use the System.Numerics.Complex type instead of double to store your roots:
using System.Numerics;
using MathNet.Numerics;
class Program
{
static void Main()
{
double d = 0, c = -1, b = 0, a = 1; // x^3 - x
var roots = FindRoots.Cubic(d, c, b, a);
Complex root1 = roots.Item1;
Complex root2 = roots.Item2;
Complex root3 = roots.Item3;
}
}
If you only want to deal with real numbers, call MathNet.Numerics.RootFinding.Cubic.RealRoots instead (which will return any complex-valued roots as Double.NaN):
using MathNet.Numerics.RootFinding;
...
var roots = Cubic.RealRoots(d, c, b); // "a" is assumed to be 1
double root1 = roots.Item1;
double root2 = roots.Item2;
double roo13 = roots.Item3;

Related

Adding two columns using Deedle in C#

Given the following CSV file
A,B
2,3
5,7
9,11
I'd like to add the two columns, resulting in
A,B,C
2,3,5
5,7,12
9,11,20
using C# and Deedle.
using Deedle;
using System.IO;
using System.Linq;
namespace NS
{
class AddTwoColumns
{
static void main(string[] args)
{
var root = "path/to";
var df = Frame.ReadCsv(Path.Combine(root, "data.csv"));
var a = df.GetColumn<int>("A");
var b = df.GetColumn<int>("B");
var c = df.Select(x => x.a + x.b);
df.AddColumn("C", c);
df.Print();
}
}
}
Neither the
reference
nor the tutorial
(series,
frame)
is particularly illuminating.
What is the correct df.Select() for this simple operation?
a and b are just Deedle.Series which you can perform numerical operations on. So, you can do this just by adding both series:
// simply add the series
var c = a + b;
df.AddColumn("C", c);
df.Print();
// output
A B C
0 -> 2 3 5
1 -> 5 7 12
2 -> 9 11 20
The Statistics and calculations section (of the page you linked to) briefly mentions arithmetic operations. It also features a note on missing data which you might need to consider:
Point-wise and scalar operators automatically propagate missing data.
When calculating s1 + s2 and one of the series does not contain data
for a key k, then the resulting series will not contain data for k.
I know this question is particularly addressed for C#, but I hope this F# approach can help somehow:
Frame.ReadCsv(#"C:\Users\flavi\Downloads\sample.txt")
|> fun frame->
Frame.addCol "C"
(Frame.mapRowValues (fun row ->
row.GetAs<int>("A") + row.GetAs<int>("B")
)frame) frame

Pitfalls in C# for a new user. (FWHM calculation)

This is my idea to program a simple math module (function) that can be called from another main program. It calculates the FWHM(full width at half the max) of a curve. Since this is my first try at Visual Studio and C#. I would like to know few basic programming structures I should learn in C# coming from a Mathematica background.
Is double fwhm(double[] data, int c) indicate the input arguments
to this function fwhm should be a double data array and an Integer
value? Did I get this right?
I find it difficult to express complex mathematical equations (line 32/33) to express them in parenthesis and divide one by another, whats the right method to do that?
How can I perform Mathematical functions on elements of an Array like division and store the results in the same Array?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DEV_2
{
class fwhm
{
static double fwhm(double[] data, int c) // data as 2d data and c is integer
{
double[] datax;
double[] datay;
int L;
int Mag = 4;
double PP = 2.2;
int CI;
int k;
double Interp;
double Tlead;
double Ttrail;
double fwhm;
L = datay.Length;
// Create datax as index for the number of elemts in data from 1-Length(data).
for (int i = 1; i <= data.Length; i++)
{
datax[i] = (i + 1);
}
//Find max in datay and divide all elements by maxValue.
var m = datay.Length; // Find length of datay
Array.ForEach(datay, (x) => {datay[m++] = x / datay.Max();}); // Divide all elements of datay by max(datay)
double maxValue = datay.Max();
CI = datay.ToList().IndexOf(maxValue); // Push that index to CI
// Start to search lead
int k = 2;
while (Math.Sign(datay[k]) == Math.Sign(datay[k-1]-0.5))
{
k=k+1;
}
Interp = (0.5-datay[k-1])/(datay[k]-datay[k-1]);
Tlead = datax[k-1]+Interp*(datax[k]-datax[k-1]);
CI = CI+1;
// Start search for the trail
while (Math.Sign(datay[k]-0.5) == Math.Sign(datay[k-1]-0.5) && (k<=L-1))
{
k=k+1;
}
if (k != L)
{
Interp = (0.5-datay[k-1])/(datay[k]-datay[k-1]);
Ttrail = datax[k-1] + Interp*(datax[k]-datax[k-1]);
fwhm =((Ttrail-Tlead)*PP)/Mag;
}
}//end main
}//end class
}//end namespace
There are plenty of pitfalls in C#, but working through problems is a great way to find and learn them!
Yes, when passing parameters to a method the correct syntax is MethodName(varType varName) seperated by a comma for multiple parameters. Some pitfalls arise here with differences in passing Value types and Reference types. If you're interested here is some reading on the subject.
Edit: As pointed out in the comments you should write code as best as possible to require as few comments as possible (thus paragraph between #3 and #4), however if you need to do very specific and slightly complex math then you should comment to clarify what is occuring.
If you mean difficulties understanding, make sure you comment your code properly. If you mean difficulties writing it, you can create variables to simplify reading your code (but generally unnecessary) or look up functions or libraries to help you, this is a bit open ended question if you have a particular functionality you are looking for perhaps we could be of more help.
You can access your array via indexes such as array[i] will get the ith index. Following this you can manipulate the data that said index is pointing to in any way you wish, array[i] = (array[i]/24)^3 or array[i] = doMath(array[i])
A couple things you can do if you like to clean a little, but they are preference based, is not declare int CI; int k; in your code before you initialize them with int k = 2;, there is no need (although you can if it helps you). The other thing is to correctly name your variables, common practice is a more descriptive camelCase naming, so perhaps instead of int CI = datay.ToList().IndexOf(maxValue); you coud use int indexMaxValueYData = datay.ToList().IndexOf(maxValue);
As per your comment question "What would this method return?" The method will return a double, as declared above. returnType methodName(parameters) However you need to add that in your code, as of now I see no return line. Such as return doubleVar; where doubleVar is a variable of type double.

Import F# block of code into C# application [duplicate]

This question already has answers here:
Run F# code in C# - (Like C# in C# using Roslyn)
(3 answers)
Closed 9 years ago.
I was looking for solution to import F# block of code into C# application (in order to gain calculation speed of some operations I have). Therefore I install FSharpx.Core to my C# solution in MS Visual Studio Express 2013.
And that's it...don't know how to continue :-)
Can someone help me with some simple code - e.g. when I click a button in the form, to subtract variable v1 and v2.
Form1.cs
...
private void buttonCalcVars_Click(object sender, EventArgs e)
{
int sum = CallFSharpFunction(1,2);
}
// This should be some F# block of code
private int CallFSharpFunction(int a, int b)
{
let v1 = a;
let v2 = b;
// do some calculations
return result;
}
...
Hope this is possible,
Thank you!
Before using F # one wonders, can you use an F # function in applications written in c #.
Become familiar with functional language F # you can, for example, at this address: http://msdn.microsoft.com/ru-ru/magazine/cc164244.aspx
But here, in my opinion, F # functional language is good for writing various mathematical functions (excuse my tautology), but why take the bread from the object-oriented languages, why put unintelligible code to work with WinForms or WebForms controls pages in F #? Because I immediately wondered how to invoke a function from F # assemblies. Just want to say that because there are difficulties in functional languages with tipizaciâmi when writing code, in the case of using F # functions from C # assemblies these difficulties only increase. Get down to business.
Create a project that includes, for example, the C # console application and an F # Assembly.
F # in the Assembly we need one file MyFunctions. fs. Here we describe some of the features that we believe it is easier for us to write at a functional language. For example, even if it is the translation function array bitmap images from RGB to YCbCr color space (this is just an example). Entry in F # can be roughly this:
open System
let RGB_to_YCbCr (r : double,g : double,b : double) =
let y = 0.299 * r + 0.587 * g + 0.114 * b in
let Cb = (-0.1687) * r - 0.3313 * g + 0.5 * b + 128.0 in
let Cr = 0.5 * r - 0.4187 * g - 0.0813 * b + 128.0 in
(y,Cb,Cr);
let RGB_to_YCbCr_v (v : _ array) =
RGB_to_YCbCr (v.[0], v.[1], v.[2]);
let Process (image : _ array) =
let lenght = Array.length image in
let imageYCbCr = Array.create lenght (0.0, 0.0, 0.0) in
for index = 0 to lenght - 1 do
imageYCbCr.[index] <- RGB_to_YCbCr_v (image.[index])
done
imageYCbCr
After Assembly, we can see that access to features not just have weird views the namespace, and how to use them is not clear. See the location of the functions in the Assembly we can using Reflector.
In order to describe the namespace and the class you need to add the following line immediately after #light:
module FSharp.Sample.MyFunctions
That said, the fact that all the functions written below will contain the class MyFunctions fsharp.Core namespace.
After the project again, we will see that in the Assembly have a clear the fsharp.Core namespace Sample that has the class MyFunctions static methods, which we have described above.
Read more in our console application, we set the Reference to the Assembly the fsharp.core Sample is the name of my Assembly to F # and the fsharp.core -in order to use types (classes) of the F # type Triple. And write the following code:
using System;
using FSharp.Sample;
namespace CSharp.Sample.Console
{
class Program
{
static void Main()
{
double[][] image = new double[1000][];
Random rand = new Random();
for (int i = 0; i < 1000; i ++ )
{
image[i] = new double[3];
image[i][0] = rand.Next();
image[i][1] = rand.Next();
image[i][2] = rand.Next();
}
foreach (var doubles in MyFunctions.Process(image))
{
System.Console.WriteLine(doubles);
}
}
}
}
Where initially we specify to use the fsharp.Core namespace. In the code we generate an array of data and pass it to the function MyFunction. Process, which converts it to the chosen algorithm. We are returned as an array of data types "in Microsoft fsharp.core.. Tuple'3".

minpack fortran .dll for use in c#

I am trying to include minpack, which is written in FORTRAN and is used for least square solutions to underdetermined maths problems, in my c# windows form solution.
I have read that it is possible to compile the minpack fortran subroutines, of which there are 7 (all in separate files) into a .dll, which I can then add as a reference to my c# program in visual studio 2012.
I have been attempting to do this now for 2 days with not much luck. I have downloaded GCC GNU to compile the fortran files. My steps so far are:
1) compile fortran files to Common Object File Format (COFF *.o) files using the syntax "gcc -c filename1.f" in the mingw64env command prompt for all 7 files
2) I have then compiled these files together into a shared executable using the syntax "gcc -shared -o mindpack.dll filename1.o filename2.o filename3.o..."
this outputs a .dll file with no reported errors.
3) But when I try to add it as a reference to my windows forms project (c#) I get the error message "A reference to '*.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component."
4) one of the suggestions to fix this was to find the file C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\TlbImp.exe and execute it with the syntax "TlbImp.exe minpack.dll" but this gives the error "TlbImp : error T10000 : The input file 'C:\mingw64\minpack.dll' is not a valid type library.
Could anyone point me in the right direction as I've only started learning c# and some of the solutions online are over my head with things like header files and DEF files, im not sure if these are even relevant.
If someone could lay out a solution to converting a collection of fortran subroutines into a single .dll file that can be called from c#, preferably using GCC GNU (or some other free software), it would be much appreciated.
Thanks in advance.
Unmanaged dll can't be added as a reference to a C# application. GCC can not easily link COM object for you.
If the dll exports a number of global functions, then you should be able to use Platfrom Invoke (DllImport attribute) to call them from C#
Please look at this article or any other from Google search.
This answer is somewhat orthogonal to the question as it avoids Fortran entirely, but given the prevalence of the question in search results on C# and MINPACK, it is worth mentioning that an open source C/C++ port of MINPACK is available, which may simplify the process of making something callable from .NET.
To use this particular library,
download a release version of the source code, the most recent at the time of writing being 1.6.3.
Open the Visual C++ solution, cminpack.sln, contained within, and build it to obtain the library, cminpack_dll.dll.
Add cminpack_dll.dll to your .NET solution and make sure that it is copied to the output directory when building.
At this point, the library can be called using P/Invoke.
The example below shows how to fit a quadratic function to a given collection of data points:
class Program
{
static void Main()
{
// Define some test data by 5i + 3i^2. The plan is to let cminpack figure out
// the values 5 and 3.
var data = Enumerable.Range(0, 20)
.Select(i => 5 * i + 3 * Math.Pow(i, 2))
.ToList();
CminpackFuncMn residuals = (p, m, n, x, fvec, iflag) =>
{
unsafe
{
// Update fvec with the values of the residuals x[0]*i + x[1]*i^2 - data[i].
var fvecPtr = (double*)fvec;
var xPtr = (double*)x;
for (var i = 0; i < m; i++)
*(fvecPtr + i) = *xPtr * i + *(xPtr + 1) * Math.Pow(i, 2) - data[i];
}
return 0;
};
// Define an initial (bad) guess for the value of the parameters x.
double[] parameters = { 2d, 2d };
var numParameters = parameters.Length;
var numResiduals = data.Count;
var lwa = numResiduals * numParameters + 5 * numParameters + numResiduals;
// Call cminpack
var info = lmdif1(
fcn: residuals,
p: IntPtr.Zero,
m: numResiduals,
n: numParameters,
x: parameters,
fvec: new double[numResiduals],
tol: 0.00001,
iwa: new int[numParameters],
wa: new double[lwa],
lwa: lwa);
// parameters now contains { 5, 3 }.
Console.WriteLine($"Return value: {info}, x: {string.Join(", ", parameters)}");
}
[DllImport("cminpack_dll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int lmdif1(CminpackFuncMn fcn, IntPtr p, int m, int n, double[] x,
double[] fvec, double tol, int[] iwa, double[] wa, int lwa);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CminpackFuncMn(IntPtr p, int m, int n, IntPtr x, IntPtr fvec, int iflag);
}
Here, the signatures of lmdif1 and CminpackFuncMn can be deduced through inspection of the relevant header file in cminpack.

Finding all nth roots of a complex number in C#

Consider a generic complex number:
System.Numerics.Complex z = new System.Numerics.Complex(0,1); // z = i
And now consider the n-th root extraction operation of z. As you all know, when having a problem like z^n = w (having z and w complex numbers and n a positive not null integer) the equation returns n different complex numbers all residing on the complex circle having its radius equal to the module of z (|z|).
In the System.Numerics namespace I could not find such a method. I obviousle need some sort of method like this:
Complex[] NRoot(Complex number);
How can I find this method. Do I really need to implement it myself?
How can I find this method.
You can't, it's not built into the Framework.
Do I really need to implement it myself?
Yes.
Sorry if this comes across as a tad flip, I don't mean to, but I suspect that you already knew this would be the answer.
That said, there's no magic to it:
public static class ComplexExtensions {
public static Complex[] NthRoot(this Complex complex, int n) {
Contract.Requires(n > 0);
var phase = complex.Phase;
var magnitude = complex.Magnitude;
var nthRootOfMagnitude = Math.Pow(magnitude, 1.0 / n);
return
Enumerable.Range(0, n)
.Select(k => Complex.FromPolarCoordinates(
nthRootOfMagnitude,
phase / n + k * 2 * Math.PI / n)
)
.ToArray();
}
}
Most of the work is offloaded to the Framework. I trust that they've implemented Complex.Phase, Complex.Magnitude correctly ((Complex complex) => Math.Sqrt(complex.Real * complex.Real + complex.Imaginary * complex.Imaginary) is bad, Bad, BAD) and Math.Pow correctly.

Categories

Resources