BetaInv function in SQL Server - c#

similarly to the question: Inverted beta in MySQL I need to use the BetaInv function inside a SQL Server stored procedure.
function is described here: Excel's BETAINV
is anybody aware of anything similar in TSQL or would you wrap it in a CLR .NET managed SQL user defined function?
I really need to use it within the stored procedure and not as post executing code in the C# side after data has been retrieved with the stored procedure because I should keep all logic on the db server for better reuse.
can I assume that a .NET managed udf running in the SQL Server would perform as fast as a normal native TSQL function?
Thanks!

I've in the end implemented the whole function myself, here the source code in case somebody needs it:
public static class UDFs
{
private const int MAXIT = 100;
private const double EPS = 0.0000003;
private const double FPMIN = 1.0E-30;
[SqlFunction(Name = "BetaInv", DataAccess = DataAccessKind.Read)]
public static SqlDouble BetaInv(SqlDouble p, SqlDouble alpha, SqlDouble beta, SqlDouble A, SqlDouble B)
{
return InverseBeta(p.Value, alpha.Value, beta.Value, A.Value, B.Value);
}
private static double InverseBeta(double p, double alpha, double beta, double A, double B)
{
double x = 0;
double a = 0;
double b = 1;
double precision = Math.Pow(10, -6); // converge until there is 6 decimal places precision
while ((b - a) > precision)
{
x = (a + b) / 2;
if (IncompleteBetaFunction(x, alpha, beta) > p)
{
b = x;
}
else
{
a = x;
}
}
if ((B > 0) && (A > 0))
{
x = x * (B - A) + A;
}
return x;
}
private static double IncompleteBetaFunction(double x, double a, double b)
{
double bt = 0;
if (x <= 0.0)
{
return 0;
}
if (x >= 1)
{
return 1;
}
bt = System.Math.Exp(Gammln(a + b) - Gammln(a) - Gammln(b) + a * System.Math.Log(x) + b * System.Math.Log(1.0 - x));
if (x < ((a + 1.0) / (a + b + 2.0)))
{
// Use continued fraction directly.
return (bt * betacf(a, b, x) / a);
}
else
{
// Use continued fraction after making the symmetry transformation.
return (1.0 - bt * betacf(b, a, 1.0 - x) / b);
}
}
private static double betacf(double a, double b, double x)
{
int m, m2;
double aa, c, d, del, h, qab, qam, qap;
qab = a + b; // These q’s will be used in factors that occur in the coe.cients (6.4.6).
qap = a + 1.0;
qam = a - 1.0;
c = 1.0; // First step of Lentz’s method.
d = 1.0 - qab * x / qap;
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
d = 1.0 / d;
h = d;
for (m = 1; m <= MAXIT; ++m)
{
m2 = 2 * m;
aa = m * (b - m) * x / ((qam + m2) * (a + m2));
d = 1.0 + aa * d; //One step (the even one) of the recurrence.
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
c = 1.0 + aa / c;
if (System.Math.Abs(c) < FPMIN)
{
c = FPMIN;
}
d = 1.0 / d;
h *= d * c;
aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
d = 1.0 + aa * d; // Next step of the recurrence (the odd one).
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
c = 1.0 + aa / c;
if (System.Math.Abs(c) < FPMIN)
{
c = FPMIN;
}
d = 1.0 / d;
del = d * c;
h *= del;
if (System.Math.Abs(del - 1.0) < EPS)
{
// Are we done?
break;
}
}
if (m > MAXIT)
{
return 0;
}
else
{
return h;
}
}
public static double Gammln(double xx)
{
double x, y, tmp, ser;
double[] cof = new double[] { 76.180091729471457, -86.505320329416776, 24.014098240830911, -1.231739572450155, 0.001208650973866179, -0.000005395239384953 };
y = xx;
x = xx;
tmp = x + 5.5;
tmp -= (x + 0.5) * System.Math.Log(tmp);
ser = 1.0000000001900149;
for (int j = 0; j <= 5; ++j)
{
y += 1;
ser += cof[j] / y;
}
return -tmp + System.Math.Log(2.5066282746310007 * ser / x);
}
}
}
as you can see in the code, the SqlFunction is calling the InverseBeta private method which does the job using couple of other methods.
results are the same of Excel.BetaInv up to 5 or 6 digits after comma.

Related

Is there mathematical gamma function in C#?

I'd like to make a scientific calculator in C#, but I didn't find gamma function to
calculate fractal factorials.
The function's description is below:
https://en.wikipedia.org/wiki/Gamma_function
How can I reach gamma function in C#?
Install the Math.NET package from nuget
Documentation on the Gamma Function : https://numerics.mathdotnet.com/Functions.html
The Math.NET package is indeed an easy way to get the gamma function. Please keep in mind that gamma(x) is equal to (x-1)!. So, gamma(4.1) = 6.813 while 4.1! = 27.932. To get 4.1! from gamma(4.1), you can multiply gamma(4.1) by 4.1, or simply take the gamma of 5.1 instead. (I see no need to show a bunch of digits of precision here.)
In C#:
using MathNet.Numerics; //at beginning of program
private double Factorial(double x)
{
double r = x;
r *= SpecialFunctions.Gamma(x);
return r;
//This could be simplified into:
//return x * SpecialFunctions.Gamma(x);
}
private double Factorial2(double x)
{
double r;
r = SpecialFunctions.Gamma(x + 1);
return r;
}
If for some reason you don't want to use Math.Net, you can write your own gamma function as follows:
static int g = 7;
static double[] p = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
Complex MyGamma(Complex z)
{
// Reflection formula
if (z.Real < 0.5)
{
return Math.PI / (Complex.Sin(Math.PI * z) * MyGamma(1 - z));
}
else
{
z -= 1;
Complex x = p[0];
for (var i = 1; i < g + 2; i++)
{
x += p[i] / (z + i);
}
Complex t = z + g + 0.5;
return Complex.Sqrt(2 * Math.PI) * (Complex.Pow(t, z + 0.5)) * Complex.Exp(-t) * x;
}
}
Note that you can replace the data type Complex with double and the Complex. functions with Math. if you don't need complex numbers, like so:
double MyGammaDouble(double z)
{
if (z < 0.5)
return Math.PI / (Math.Sin(Math.PI * z) * MyGammaDouble(1 - z));
z -= 1;
double x = p[0];
for (var i = 1; i < g + 2; i++)
x += p[i] / (z + i);
double t = z + g + 0.5;
return Math.Sqrt(2 * Math.PI) * (Math.Pow(t, z + 0.5)) * Math.Exp(-t) * x;
}
This is from an old wiki page (which has been replaced) but is copied here.

mandel-number formula "string does not contain a constructor that takes 0 arguments"

(I'm a beginner to both programming and this website. In advance: I appologize if I make any mistakes in terms of using this website the wrong way.)
(using C#)
I'm trying to write a method to calculate mandel-numbers (with the intent of using the method in another program) but I've got an error message saying:
" Error 1 'string' does not contain a constructor that takes 0 arguments "
Before this it was "not all code paths return a value", but I think I fixed that with convert.tostring. This error however, is new to me.
I have no idea what this means, could anyone explain what the problem is?
using System;
namespace WindowsFormsApplication1{
public class formule
{
static int Main()
{
double f = new double();
double x = new double();
double y = new double();
double a = new double();
double b = new double();
int n = new int();
double max = new double();
double schaal = new double();
double afstand = new double();
x = 0.5;
y = 0.8;
n = 0;
a = 0;
b = 0;
max = 100;
//schaal = invoer 4
afstand = 0;
while (afstand <= 2 || n < max)
{
afstand = Math.Sqrt((a * a) + (b * b));
n++;
a = (a * a - b * b + x);
b = (2 * a * b + y);
}
string mandelgetal;
mandelgetal = new string();
mandelgetal = Convert.ToString(n);
Console.WriteLine(mandelgetal);
Console.ReadLine();
}
}
}
It means 'string' does not contain a constructor that takes 0 arguments
If you want an empty string initialize your variable with string.Empty or assign it to null to avoid uninitialized variable errors.
In addition to that you can see all the public constructors of String class here and you will notice that there is no parameterless constructor.
You have a problem on this line (well, some other problems, but the blocking one) is
mandelgetal = new string();
as there's no ctor without argument for string (and here, you have nothing between your parenthesis).
So you could just do
var mandelgetal = string.Empty;
or
var mandeldetal = Convert.ToString(n);
but it would really be easier to remove these lines :
string mandelgetal;
mandelgetal = new string();
mandelgetal = Convert.ToString(n);
and just do
Console.WriteLine(n);
as Console.WriteLine can take an int as argument.
EDIT
I would rewrite all that with (assuming your algo is correct)
const double X = 0.5;
const double Y = 0.8;
const double Max = 100;
int n = 0;
double afstand = 0;
double a = 0;
double b = 0;
while (afstand <= 2 || n < Max) {
afstand = Math.Sqrt((a * a) + (b * b));
n++;
a = (a * a - b * b + X);
b = (2 * a * b + Y);
}
Console.WriteLine(n);
Console.ReadLine();
You are producing a lot of unnecessary code. Have a look below what is necessary:
public class formule
{
static void Main()
{
double f;
double x = 0.5;
double y = 0.8;
double a;
double b;
int n;
double max = 100.0;
double schaal;
double afstand;
while (afstand <= 2 || n < max)
{
afstand = Math.Sqrt((a * a) + (b * b));
n++;
a = (a * a - b * b + x);
b = (2 * a * b + y);
}
string mandelgetal = n.ToString();
Console.WriteLine(mandelgetal);
Console.ReadLine();
}
}
Everything else is just a potential for errors. In your case, you called a constructor that does not exist. If you don't know what a constructor is yet, don't use them, keep it simple like above and continue with the exercises, the chapter will come sooner or later.

Mistake passing parameters for simple RGB to HSL color converter

Okay I am trying to follow this guide to making a converter in c#: http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm
here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace ColorPickerTest
{
// Given a Color (RGB Struct) in range of 0-255
// Return H,S,L in range of 0-1
class Program
{
public struct ColorRGB
{
public byte R;
public byte G;
public byte B;
public ColorRGB(Color value)
{
this.R = value.R;
this.G = value.G;
this.B = value.B;
}
public static implicit operator Color(ColorRGB rgb)
{
Color c = Color.FromArgb(rgb.R, rgb.G, rgb.B);
return c;
}
public static explicit operator ColorRGB(Color c)
{
return new ColorRGB(c);
}
}
public static void RGB2HSL(ColorPickerTest.Program.ColorRGB rgb, out double h, out double s, out double l)
{
double r = rgb.R / 255.0;
double g = rgb.G / 255.0;
double b = rgb.B / 255.0;
double v;
double m;
double vm;
double r2, g2, b2;
h = 0; // default to black
s = 0;
l = 0;
v = Math.Max(r, g);
v = Math.Max(v, b);
m = Math.Min(r, g);
m = Math.Min(m, b);
l = (m + v) / 2.0;
if (l <= 0.0)
{
return;
}
vm = v - m;
s = vm;
if (s > 0.0)
{
s /= (l <= 0.5) ? (v + m) : (2.0 - v - m);
}
else
{
return;
}
r2 = (v - r) / vm;
g2 = (v - g) / vm;
b2 = (v - b) / vm;
if (r == v)
{
h = (g == m ? 5.0 + b2 : 1.0 - g2);
}
else if (g == v)
{
h = (b == m ? 1.0 + r2 : 3.0 - b2);
}
else
{
h = (r == m ? 3.0 + g2 : 5.0 - r2);
}
h /= 6.0;
}
static void Main(string[] args)
{
Color slateBlue = Color.FromName("SlateBlue");
byte g = slateBlue.G;
byte b = slateBlue.B;
byte r = slateBlue.R;
byte a = slateBlue.A;
string text = String.Format("Slate Blue has these ARGB values: Alpha:{0}, " +
"red:{1}, green: {2}, blue {3}", new object[]{a, r, g, b});
Console.WriteLine(text);
Console.ReadKey();
ColorPickerTest.Program.ColorRGB rgb = new ColorPickerTest.Program.ColorRGB(slateBlue);
double h, s, l;
RGB2HSL(rgb, h, s, l);
}
}
}
I am getting an error when i call the final method: 'RGB2HSL', saying the method has invalid arguments.
Not sure if it is to do with my overloaded struct for ColorRGB, or if I am meant to be qualifying it
You just forgot the word out into the function calling
RGB2HSL(rgb, out h, out s, out l);
Let me know if this solved your problem.

Elliptic curve factorisng in c# 4.0

I am trying to implement Elliptic curve factorisation in c# 4.
I have a few problems though.
Firstly, my version appears to be invredibly slow. Factorising 89041 * 93563 has taken about 5 minutes on a 2GHZ dual core machine and required computing 273!P.
Also I haven't been able to find a profiler for c# 4 to determine what is actually taking the time however I suspect that the O(log(N)) recursive calls in CalcNP are probably not very fast when N >> 100!.
Any help on making this run faster?
Code:
using System;
using System.Collections.Generic;
using bint = System.Numerics.BigInteger;
namespace ECM
{
public class Program
{
static Tuple<bint, bint>[] pow2store; //caches the values of 2^n * P
static bint Factor;
static bint max2powstored = 0;
static int maxexp = 0;
public static void Main(string[] args)
{
pow2store = new Tuple<bint, bint>[100000];
bint n = 89041 * (bint)93563;
//curve params from wiki article
bint x = 1;
bint y = 1;
bint a = 5;
bint b = (y * y - x * x * x - a * x) % n;
bool ftest = false;
var P = new Tuple<bint, bint>(x, y);
pow2store[0] = P;
var twop = twoP(b, P, n, out ftest);
pow2store[1] = twop;
int factsteps = 1;
bint factorial = 1;
while (!ftest)
{
factorial *= ++factsteps;
Console.WriteLine("calculating {0}! p", factsteps);
CalcNP(factorial, b, n, out ftest);
}
Console.WriteLine("{0} = {1} * {2}", n, Factor, n / Factor);
Console.ReadKey(true);
}
static Tuple<bint, bint> CalcNP(bint calc, bint b, bint n, out bool res)
{
int powguess = (int)Math.Floor(bint.Log(calc, 2));
powguess = Math.Min(powguess, maxexp);
bint max2pow = bint.Pow(2, (int)powguess);
while (max2pow * 2 <= calc)
{
max2pow *= 2;
powguess++;
if (max2pow > max2powstored)
{
maxexp++;
max2powstored = max2pow;
pow2store[powguess] = twoP(b, pow2store[powguess - 1], n, out res);
if (res)
{
return pow2store[powguess];
}
}
}
calc -= max2pow;
if (calc > 1)
{
var Q = CalcNP(calc, b, n, out res);
if (res)
{
return new Tuple<bint, bint>(0, 0);
}
return ECadd(pow2store[powguess], Q, n, out res);
}
else
{
res = false;
return pow2store[powguess];
}
}
static Tuple<bint, bint> twoP(bint b, Tuple<bint, bint> P, bint n, out bool Factor)
{
bint stop = (3 * P.Item1 * P.Item1 - b) % n;
bint sbottom = (2 * P.Item2) % n;
bint inv = ModInv(sbottom, n, out Factor);
if (Factor)
{
return new Tuple<bint, bint>(0, 0);
}
bint s = (stop * inv) % n;
bint xR = (s * s - 2 * P.Item1) % n;
bint yR = (s * (P.Item1-xR)-P.Item2) % n;
return new Tuple<bint, bint>(xR, yR);
}
static Tuple<bint, bint> ECadd(Tuple<bint, bint> P, Tuple<bint, bint> Q, bint n, out bool Factor)
{
bint stop = P.Item2 - Q.Item2 % n;
bint sbottom = (P.Item1 - Q.Item1) % n;
bint inv = ModInv(sbottom, n, out Factor);
if (Factor)
{
return new Tuple<bint, bint>(0, 0);
}
bint s = (stop * inv) % n;
bint xR = (s * s - P.Item1 - Q.Item1) % n;
bint yR = (s * (xR-P.Item1) - P.Item2) % n;
return new Tuple<bint, bint>(xR, yR);
}
static bint ModInv(bint a, bint m, out bool notcoprime)
{
bint[] arr = ExtGCD(a, m);
if (!bint.Abs(arr[2]).IsOne)
{
Console.WriteLine("found factor when inverting {0} mod {1}", (a + m) % m, m);
Factor = arr[2];
notcoprime = true;
return 0;
}
else
{
notcoprime = false;
return arr[0];
}
}
//extended euclidean
static bint[] ExtGCD(bint a, bint b)
{
bint x = 0;
bint y = 1;
bint u = 1;
bint v = 0;
while (b != 0)
{
bint buffer = b;
bint q = a / b;
b = a % b;
a = buffer;
buffer = x;
x = u - q * x;
u = buffer;
buffer = y;
y = v - q * y;
v = buffer;
}
return new bint[] { u, v, a };
}
}
}
You do realize that this kind of factorization was designed to be computationally infeasible?
Looking at your code though, there's nothing in there that's exceptionally slow, except maybe the BigInteger type itself. However, if you need arbitrary sized integers that's the price you pay.
If this is just a mathematical exercise I'd consider myself done unless you wanna explore a different factorization algorithm for which there exist no algorithm that terminate with an optimal solution in polynomial time.
I should add that only given that the problem was designed to be hard to compute is there no feasible way to do factorization. I was automatically thinking cracking encryption which might have been confusing to some people.

Lambda expression exercise

I have been trying to learn more about lambda expressions lately, and thought of a interesting exercise...
is there a way to simplify a c++ integration function like this:
// Integral Function
double integrate(double a, double b, double (*f)(double))
{
double sum = 0.0;
// Evaluate integral{a,b} f(x) dx
for(int n = 0 ; n <= 100; ++n)
{
double x = a + n*(b-a)/100.0;
sum += (*f)(x) * (b-a)/101.0;
}
return sum;
}
by using c# and lambda expressions?
What about this:
public double Integrate(double a,double b, Func<double, double> f)
{
double sum = 0.0;
for (int n = 0; n <= 100; ++n)
{
double x = a + n * (b - a) / 100.0;
sum += f(x) * (b - a) / 101.0;
}
return sum;
}
Test:
Func<double, double> fun = x => Math.Pow(x,2);
double result = Integrate(0, 10, fun);
Lambda Powa! Not sure whether this is right (No C# programmer! Just liking its lambda stuff)
(a, b, c) => {
double sum = 0.0;
Func<double, double> dox = (x) => a + x*(b-a)/100.0;
// Evaluate integral{a,b} f(x) dx
for(int n = 0 ; n <= 100; ++n)
sum += c(dox(n)) * (b-a)/101.0;
return sum;
}
Ok, so i think while the code is C++, why not keep it C++ and get lambda in? Here it is how it looks for c++0x, being hopefully released as a Standard very soon :
static double Integrate(double a, double b, function<double(double)> f)
{
double sum = 0.0;
// Evaluate integral{a,b} f(x) dx
for(int n = 0; n < 100; ++n) {
double x = a + n * (b - a) / 100.0;
sum += f(x) * (b - a) / 101.0;
}
return sum;
}
int main() {
Integrate(0, 1, [](double a) { return a * a; });
}
The real power comes, as stated, when calling it. For example, in C#
static double Integrate(double a, double b, Func<double, double> func)
{
double sum = 0.0;
// Evaluate integral{a,b} f(x) dx
for(int n = 0 ; n <= 100; ++n)
{
double x = a + n*(b-a)/100.0;
sum += func(x) * (b - a) / 101.0;
}
return sum;
}
Then:
double value = Integrate(1,2,x=>x*x); // yields 2.335
// expect C+(x^3)/3, i.e. 8/3-1/3=7/3=2.33...

Categories