I cannot seem to find any builtin factorial function in .Net, which I find incredible strange.
In many languages, for example python, there is a factorial function in the standard libraries...
I do not want to make my own factorial function each time I need one
in a solution.
I would prefer not to get some library from Nuget just to get a
factorial function, that is just silly...
I wish to use a factorial function in both F# and C#.
Google searches drown in people who wants to write or show how to write your own factorial function.
Am I overlooking the factorial function, or is there really no built in factorial function in System.Math, System.Numerics or anywhere else? (and if no factorial function exists in any standard libraries, then what is the motivation for not having this function in any standard library?)
Yes I know it is simple to write, and can be defined like for example
let rec factorial = function
| x when x = 0 -> 1
| x -> x*factorial(x-1)
But I don't want to write that every single time I need this function, and it also feels silly to make my own library just for this kind of simple function...
You can utilise the BigInteger class for that
However, this should do the trick if you're interested in a perfomant solution with primitive types:
private static readonly int[] factorial = new int[]{
1,
1,
2,
6,
24,
120,
720,
5040,
40320,
362880,
3628800,
39916800,
479001600,
1932053504,
};
public static int Factorial(int x) {
if(x < 0) {
throw new ArithmeticException("negative faculty");
}
if(x >= faculty.Length) {
throw new OverflowException();
}
return faculty[x];
}
Related
So i am working on a program to factor a given number. you write a number in the command line and it gives you all the factors. now, doing this sequentially is VERY slow. because it uses only one thread, if i'm not mistaking. now, i thought about doing it with Parallel.For and it worked, only with integers, so wanted to try it with BigIntegers
heres the normal code:
public static void Factor(BigInteger f)
{
for(BigInteger i = 1; i <= f; i++)
{
if (f % i == 0)
{
Console.WriteLine("{0} is a factor of {1}", i, f);
}
}
}
the above code should be pretty easy to understand. but as i said, this Very slow for big numbers (above one billion it starts to get impractical) and heres my parallel code:
public static void ParallelFacotr(BigInteger d)
{
Parallel.For<BigInteger>(0, d, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, i =>
{
try
{
if (d % i == 0)
{
Console.WriteLine("{0} is a factor of {1}", i, d);
}
}
catch (DivideByZeroException)
{
Console.WriteLine("Done!");
Console.ReadKey();
Launcher.Main();
}
});
}
now, the above code (parallel one) works just fine with integers (int) but its VERY fast. it factored 1000.000.000 in just 2 seconds. so i thought why not try it with bigger integers. and also, i thought that putting <Biginteger> after the parallel.for would do it. but it doesn't. so, how do you work with bigintegers in parallel for loop? and i already tried just a regular parallel loop with a bigInteger as the argument, but then it gives an error saying that it cannot convert from BigInteger to int. so how do you
Improve your algorithm efficiency first.
While it is possible to use BigInteger you will not have CPU ALU arithmetical logic to resolve arbitrarily big numbers logic in hardware, so it will be noticeably slower. So unless you need bigger numbers than 9 quintillion or exactly 9,223,372,036,854,775,807 then you can use type long.
A second thing to not is that you do not need to loop over all elements as it needs to be multiple of something, so you can reduce
for(BigInteger i = 1; i <= f; i++)
for(long i = 1; i <= Math.Sqrt(f); i++)
That would mean that instead of needing to iterate over 1000000000 items you iterate over 31623.
Additionally, if you still plan on using BigInt then check the parameters:
It should be something in the lines of
Parallel.For(
0,
(int)d,
() => BigInteger.Zero,
(x, state, subTotal) => subTotal + BigInteger.One,
Just for trivia. Some programming languages are more efficient in solving problems than others and in this case, there is a languages Wolfram (previously Mathematica) when solving problems is simpler, granted that you know what you are doing.
However they do have google alternative that answers you directly and it has a decent AI that processes your natural language to give you an exact answer as best as it could.
So finding factors of numbers is easy as:
Factor[9223372036854775809]
or use web api https://www.wolframalpha.com/input/?i=factor+9223372036854775809
You can also call Wolfram kernel from C#, but terms and conditions apply.
It is stated here that SimplexSolver "Defines a branch-and-bound search for optimizing mixed integer problems." which should mean that it finds an integer solution for a given task but it finds a precise solution with a double values.
Is there a way to force it to find an integer solution or i should implement my own branch-and-bound on top of given double solutions?
Is there a way to force it to find an integer solution or i should implement my own branch-and-bound on top of given double solutions?
No need to implement B&B algorithm, just declare your variables as integers and SimplexSolver should be able to solve it and provide integer optimal solution. See example here. Relevant snippet below:
SimplexSolver solver = new SimplexSolver();
// ...
for (int i = 0; i < 5; i++) {
solver.AddVariable(string.Format("project{0}", i),
out chooseProjectX[i]);
solver.SetBounds(chooseProjectX[i], 0, 1);
solver.SetIntegrality(chooseProjectX[i], true);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
solver.SetCoefficient(profit, chooseProjectX[i],
estimatedProfitOfProjectX[i]);
solver.SetCoefficient(expenditure, chooseProjectX[i],
capitalRequiredForProjectX[i]);
}
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.
I know there have been several questions asked relating to interpolation, but I have not found any answers that would be helpful enough for me so I have the following question.
I have two arrays of points. One tracks time (x axis) and one tracks expenses (y axis) and
I want to get something like this:
InterpolatingPolynomial[{{0, 10}, {1, 122}, {2, 3.65}, {3, 56.3}, {4, 12.4}, {5, 0}}, x]
(In Mathematica that returs a constructed polynomial that fits the points). Is it possible, to return a func<double,double> constructed from two double arrays in C#?
Thanks in advance.
This paper describes exactly what you want. The Vandermonde Determinant method is quite simple to implement as it requires to compute the determinant of a matrix in order to obtain the coefficients of the interpolating polynomial.
I'd suggest to build a class with an appropriate interface though, as building Funcs on the fly is pretty complicated (see here for an example). You could do something like:
public class CosineInterpolation {
public CosineInterpolation(double[] x, double[] y) { ... }
public double Interpolate(double x) { ... }
}
I think I found the solution myself after a long day of search. I interpolate a function using Lagrange Interpolation.
A Func<double,double> can be then easily constructed using DLINQ.
e.g
public Func<doube,double> GetFunction()
{
LagrangeInterpolation lagInter = new LagrangeInterpolation(xVals, yVals);
return ( val => lagInter(GetValue(val) );
}
This returns the Func<double,double> object. (I know that creating a new object each time is not a good solution but this is just for demonstrational purposes)
Let's say I have the following code.
var numberToGetTo = 60;
var list = new[] {10, 20, 30, 40, 50};
I want to be able to return 50 & 10 from list to = 60.
If the numberToGetTo was 100 I would want to return 50, 50.
If the numberToGetTo was 85 I would want to return 50, 40.
I want to return the least amount of numbers from the list necessary to get to the "numberToGetTo", while staying closest (equal or greather) than to it.
Is doing something like this with Linq possible?
This is an NP-complete problem called the knapsack problem. That means, that your best method is not going to be in polynomial time. You may have to brute-force a solution.
Here's an implementation that uses Linq to be as clean as possible. It makes no attempt to optimize for performance over large inputs.
I'm assuming that you wouldn't use this algorithm for large inputs anyway, since the problem is NP-Complete, and therefore clarity is the right goal. My algorithm is O(n^2), and recursive at that.
static IEnumerable<int> Knapsack(IEnumerable<int> items, int goal)
{
var matches = from i in items
where i <= goal
let ia = new[] {i}
select i == goal ? ia : Knapsack(items, goal - i).Concat(ia);
return matches.OrderBy(x => x.Count()).First();
}
This problem as currently stated is actually trivial. The easiest way to to get "equal or greater" than the target is to find the largest number A in the list, and stick it in the answer list N times, where N is the lowest N such that N * A > target.
I suspect this is not what the original poster really wants however. If the problem is restated to somehow measure the "closeness" of various answers, and make a distinction as to whether answers that are "closer" or answers that have less numbers are "better" then it becomes tougher. For example, if the target is 100, is an answer of [55,55] better or worse than an answer of [20,20,20,20,20] ?
Knapsack Problem, this may give you a clue.
http://en.wikipedia.org/wiki/Knapsack_problem
I'd say that you could create a lambda expression containing the actual alogrithm, but you'll need to use C#. Using 'just linq' will not be enough.
This sounds similar to the Subset sum problem, which can be solved in a reasonable amount of time for smallish sets using dynamic programming. It's not an easy or common problem, so you won't find a helpful Linq extension method for it :)
I just hacked this together and I'm sure someone could improve. But does something like this work?
public class App
{
static void Main(string[] eventArgs)
{
var list = new[] {10, 20, 30, 40, 50};
var whatYouNeed = GetWhatYouNeed(list, 60, 60);
//what you need will contain 50 & 10
//whatYouNeed = GetWhatYouNeed(list, 105,105);
//what you need will contain (50,50, 10)
}
private static IList<int> _whatYouNeed = new List<int>();
static IEnumerable<int> GetWhatYouNeed(IEnumerable<int> list, int goal, int amountRequired)
{ //this will make sure 20 is taken over 10, if the goal is 15. highest wins
var intYouNeed = list.OrderBy(x => Math.Abs(amountRequired - x)).FirstOrDefault(x => x > amountRequired);
if (intYouNeed == 0) intYouNeed = list.OrderBy(x => Math.Abs(amountRequired - x)).FirstOrDefault();
_whatYouNeed.Add(intYouNeed);
if (_whatYouNeed.Sum() < goal)
{
int howMuchMoreDoYouNeed = goal - _whatYouNeed.Sum();
GetWhatYouNeed(list, goal, howMuchMoreDoYouNeed);
}
return _whatYouNeed;
}
}
I was a bit lazy passing in two values to GetWhatYouNeed but you get the point.