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...
Related
Is there any difference between the following alternatives?
In this simple loop there doesn't seem to be any difference between the results, but I wonder if in some cases the different methods would result in some result discrepancy.
I would like to know whether these methods are exactly the same thing or are there some subtle differences?
x is double:
double x = 2;
double sum = 0;
while (true)
{
sum += 1 / ((x - 1) * 2);
x++;
}
x is int, but (double) before 2 in the formula:
int x = 2;
double sum = 0;
while (true)
{
sum += 1 / ((x - 1) * (double)2);
x++;
}
x is int but 2 is written as decimal:
int x = 2;
double sum = 0;
while (true)
{
sum += 1 / ((x - 1) * 2.00);
x++;
}
No difference(*) - you are stuck in an endless while loop and won't get out of it.
(*) The only way to "leave" the loop is by exception ... double takes longer to overflow if you x++ and x is of type double...
Results and their types under comment:
var a = 2; //int
var b = 2.0; //double
var c = 2d; //double
var d = 2f; //float (alias of System.Single)
var e = 2m; //decimal
var f = 2l; //long
var g = 2ul; //ulong
var h = 2.0m; //decimal
var i = 2.0f; //float
var t = 1 / 2.0; //double
var u = 1 / 2; //int!
var v = 1 / ((6 - 1) * 2); //int!
var w = 1 / 2 + 6 / 2.0 //int + double = 0 + 3 = 4
Looking on your samples:
since double takes participate in all formula, result will be double which matches with type of sum and it will be calculated properly according types
you explicity converted int to double - look #1
2.00 is double - look #1
So, all samples will be counting sum same way,
except int type will be overflowed earlier in infinite cycle
I'm getting x,y,z values from gyro-sensor. Each variable is being sent 10 values per second. In 3 seconds I have;
x=[30values]
y=[30values]
z=[30values]
Some of the values are too different from the others cause of noise. With laplace transform I need to get the most frequent value from my array.
I need to filter the array with Laplace Transform equation. I need to build the equation in C#. How can I implement the array with the equation?
Since this kind of filter (Laplace) is very specialized to certain area of Engineering and needs a person who has good understanding on both the programming language (in this case is C#) and the filter itself, I would recommend you to use such source, rather than code the filter by yourself.
Here is the snippet of the source code:
class Laplace
{
const int DefaultStehfest = 14;
public delegate double FunctionDelegate(double t);
static double[] V; // Stehfest coefficients
static double ln2; // log of 2
public static void InitStehfest(int N)
{
ln2 = Math.Log(2.0);
int N2 = N / 2;
int NV = 2 * N2;
V = new double[NV];
int sign = 1;
if ((N2 % 2) != 0)
sign = -1;
for (int i = 0; i < NV; i++)
{
int kmin = (i + 2) / 2;
int kmax = i + 1;
if (kmax > N2)
kmax = N2;
V[i] = 0;
sign = -sign;
for (int k = kmin; k <= kmax; k++)
{
V[i] = V[i] + (Math.Pow(k, N2) / Factorial(k)) * (Factorial(2 * k)
/ Factorial(2 * k - i - 1)) / Factorial(N2 - k)
/ Factorial(k - 1) / Factorial(i + 1 - k);
}
V[i] = sign * V[i];
}
}
public static double InverseTransform(FunctionDelegate f, double t)
{
double ln2t = ln2 / t;
double x = 0;
double y = 0;
for (int i = 0; i < V.Length; i++)
{
x += ln2t;
y += V[i] * f(x);
}
return ln2t * y;
}
public static double Factorial(int N)
{
double x = 1;
if (N > 1)
{
for (int i = 2; i <= N; i++)
x = i * x;
}
return x;
}
}
coded by Mr. Walt Fair Jr. in CodeProject.
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.
I'm quite new to programming so this shouldn't be a problem to most of you. I'm supposed to write a program which sums 1/n^2 (n being consecutive natural numbers) while elements are bigger than constant eps=0,001. I wrote a piece of code and tried to edit it but I'm still stuck in an infinite loop in which I just get consecutive numbers, but it's quite obvious the sum should be between 1 and 2. I'd be more than grateful if anyone could show me what it is that I'm doing wrong.
namespace program
{
class Program
{
static void Main(string[] args)
{
const double eps=0.001;
int n=1;
double x;
x = 1 / (n * n);
double sum=x;
while (x > eps)
{
n++;
sum = sum + x;
Console.WriteLine(sum);
}
Console.Write("\nSum: {0}.", sum);
Console.ReadLine();
}
}
}
You never recalculate the value of x, so the while condition never becomes false. If you move the assignment inside, your code won't loop forever.
const double eps=0.001;
int n=1;
double x;
double sum=x;
while (true)
{
x = 1.0 / (n * n);
if (x < eps) {
break;
}
n++;
sum = sum + x;
Console.WriteLine(sum);
}
Console.Write("\nSum: {0}.", sum);
Console.ReadLine();
A couple of things. First of all
1 / (n * n)
is an integer expression and is always either 0 or 1. You need to make it a floating point expression like this:
1.0 / (n * n)
And then you need to update x inside the loop rather than assigning to x once and once only.
Perhaps like this:
static void Main(string[] args)
{
const double eps = 0.001;
int n = 1;
double x = 1.0 / (n * n);
double sum = 0.0;
while (x > eps)
{
sum += x;
n++;
x = 1.0 / (n*n);
Console.WriteLine(sum);
};
Console.Write("\nSum: {0}", sum);
Console.ReadLine();
}
The downside of this is that the expression for x is written twice. So a better way is like this:
static void Main(string[] args)
{
const double eps = 0.001;
int n = 1;
double sum = 0.0;
while (true)
{
double x = 1.0 / (n * n);
if (x <= eps)
break;
sum += x;
n++;
Console.WriteLine(sum);
};
Console.Write("\nSum: {0}", sum);
Console.ReadLine();
}
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.