Data histogram - optimized binwidth optimization - c#

I'm looking to produce a data histogram from a given dataset. I've read about different options for constructing the histogram and I'm most interested in a method based on the work of
Shimazaki, H.; Shinomoto, S. (2007). "A method for selecting the bin
size of a time histogram"
The above method uses estimation to determine the optimal bin width and distribution, which is needed in my case because the sample data will vary in distribution and hard to determine the bin count and width in advance.
Can someone recommend a good source or a starting point for writing such a function in c# or have a close enough c# histogram code.
Many thanks.

The following is a port I wrote of the Python version of this algorithm from here. I know the API could do with some work, but this should be enough to get you started. The results of this code are identical to those produced by the Python code for the same input data.
public class HistSample
{
public static void CalculateOptimalBinWidth(double[] x)
{
double xMax = x.Max(), xMin = x.Min();
int minBins = 4, maxBins = 50;
double[] N = Enumerable.Range(minBins, maxBins - minBins)
.Select(v => (double)v).ToArray();
double[] D = N.Select(v => (xMax - xMin) / v).ToArray();
double[] C = new double[D.Length];
for (int i = 0; i < N.Length; i++)
{
double[] binIntervals = LinearSpace(xMin, xMax, (int)N[i] + 1);
double[] ki = Histogram(x, binIntervals);
ki = ki.Skip(1).Take(ki.Length - 2).ToArray();
double mean = ki.Average();
double variance = ki.Select(v => Math.Pow(v - mean, 2)).Sum() / N[i];
C[i] = (2 * mean - variance) / (Math.Pow(D[i], 2));
}
double minC = C.Min();
int index = C.Select((c, ix) => new { Value = c, Index = ix })
.Where(c => c.Value == minC).First().Index;
double optimalBinWidth = D[index];
}
public static double[] Histogram(double[] data, double[] binEdges)
{
double[] counts = new double[binEdges.Length - 1];
for (int i = 0; i < binEdges.Length - 1; i++)
{
double lower = binEdges[i], upper = binEdges[i + 1];
for (int j = 0; j < data.Length; j++)
{
if (data[j] >= lower && data[j] <= upper)
{
counts[i]++;
}
}
}
return counts;
}
public static double[] LinearSpace(double a, double b, int count)
{
double[] output = new double[count];
for (int i = 0; i < count; i++)
{
output[i] = a + ((i * (b - a)) / (count - 1));
}
return output;
}
}
Run it like this:
double[] x =
{
4.37, 3.87, 4.00, 4.03, 3.50, 4.08, 2.25, 4.70, 1.73,
4.93, 1.73, 4.62, 3.43, 4.25, 1.68, 3.92, 3.68, 3.10,
4.03, 1.77, 4.08, 1.75, 3.20, 1.85, 4.62, 1.97, 4.50,
3.92, 4.35, 2.33, 3.83, 1.88, 4.60, 1.80, 4.73, 1.77,
4.57, 1.85, 3.52, 4.00, 3.70, 3.72, 4.25, 3.58, 3.80,
3.77, 3.75, 2.50, 4.50, 4.10, 3.70, 3.80, 3.43, 4.00,
2.27, 4.40, 4.05, 4.25, 3.33, 2.00, 4.33, 2.93, 4.58,
1.90, 3.58, 3.73, 3.73, 1.82, 4.63, 3.50, 4.00, 3.67,
1.67, 4.60, 1.67, 4.00, 1.80, 4.42, 1.90, 4.63, 2.93,
3.50, 1.97, 4.28, 1.83, 4.13, 1.83, 4.65, 4.20, 3.93,
4.33, 1.83, 4.53, 2.03, 4.18, 4.43, 4.07, 4.13, 3.95,
4.10, 2.27, 4.58, 1.90, 4.50, 1.95, 4.83, 4.12
};
HistSample.CalculateOptimalBinWidth(x);

Check the Histogram function. If any data elements are unlucky to be equal to a bin boundary (other than the first or last bin), they will be counted in both consecutive bins.
The code needs to check (lower <= data[j] && data[j] < upper) and handle the case that all elements equal to xMax go into the last bin.

A small update to nick_w answer.
If you actually need the bins after. Plus optimized the double loop in histogram function away, plus got rid of linspace function.
/// <summary>
/// Calculate the optimal bins for the given data
/// </summary>
/// <param name="x">The data you have</param>
/// <param name="xMin">The minimum element</param>
/// <param name="optimalBinWidth">The width between each bin</param>
/// <returns>The bins</returns>
public static int[] CalculateOptimalBinWidth(List<double> x, out double xMin, out double optimalBinWidth)
{
var xMax = x.Max();
xMin = x.Min();
optimalBinWidth = 0;
const int MIN_BINS = 1;
const int MAX_BINS = 20;
int[] minKi = null;
var minOffset = double.MaxValue;
foreach (var n in Enumerable.Range(MIN_BINS, MAX_BINS - MIN_BINS).Select(v => v*5))
{
var d = (xMax - xMin)/n;
var ki = Histogram(x, n, xMin, d);
var ki2 = ki.Skip(1).Take(ki.Length - 2).ToArray();
var mean = ki2.Average();
var variance = ki2.Select(v => Math.Pow(v - mean, 2)).Sum()/n;
var offset = (2*mean - variance)/Math.Pow(d, 2);
if (offset < minOffset)
{
minKi = ki;
minOffset = offset;
optimalBinWidth = d;
}
}
return minKi;
}
private static int[] Histogram(List<double> data, int count, double xMin, double d)
{
var histogram = new int[count];
foreach (var t in data)
{
var bucket = (int) Math.Truncate((t - xMin)/d);
if (count == bucket) //fix xMax
bucket --;
histogram[bucket]++;
}
return histogram;
}

I would recommend binary search to speed up the assignment to the class intervals.
public void Add(double element)
{
if (element < Bins.First().LeftBound || element > Bins.Last().RightBound)
return;
var min = 0;
var max = Bins.Length - 1;
var index = 0;
while (min <= max)
{
index = min + ((max - min) / 2);
if (element >= Bins[index].LeftBound && element < Bins[index].RightBound)
break;
if (element < Bins[index].LeftBound)
max = index - 1;
else
min = index + 1;
}
Bins[index].Count++;
}
"Bins" is a list of items of type "HistogramItem" which defines properties like "Leftbound", "RightBound" and "Count".

Related

How can I implement array list input for string similarity algorithm?

I implemented jarowinkler algorithm. In that algorithm I have taken string source and string target. String target taking as input string source taking as array like source[0]. How can implement jarowinkler algorithm as array list input? Please see below code
public static class JaroWinklerDistance
{
private static readonly double mWeightThreshold = 0.7;
private static readonly int mNumChars = 4;
public static double distance(string source, string target)
{
return 1.0 - proximity(source, target);
}
public static double proximity(string aString1, string aString2)
{
int lLen1 = aString1.Length;
int lLen2 = aString2.Length;
if (lLen1 == 0)
return lLen2 == 0 ? 1.0 : 0.0;
int lSearchRange = Math.Max(0, Math.Max(lLen1, lLen2) / 2 - 1);
bool[] lMatched1 = new bool[lLen1];
bool[] lMatched2 = new bool[lLen2];
int lNumCommon = 0;
for (int i = 0; i < lLen1; ++i)
{
int lStart = Math.Max(0, i - lSearchRange);
int lEnd = Math.Min(i + lSearchRange + 1, lLen2);
for (int j = lStart; j < lEnd; ++j)
{
if (lMatched2[j]) continue;
if (aString1[i] != aString2[j])
continue;
lMatched1[i] = true;
lMatched2[j] = true;
++lNumCommon;
break;
}
}
if (lNumCommon == 0) return 0.0;
int lNumHalfTransposed = 0;
int k = 0;
for (int i = 0; i < lLen1; ++i)
{
if (!lMatched1[i]) continue;
while (!lMatched2[k]) ++k;
if (aString1[i] != aString2[k])
++lNumHalfTransposed;
++k;
}
int lNumTransposed = lNumHalfTransposed / 2;
double lNumCommonD = lNumCommon;
double lWeight = (lNumCommonD / lLen1
+ lNumCommonD / lLen2
+ (lNumCommon - lNumTransposed) / lNumCommonD) / 3.0;
if (lWeight <= mWeightThreshold) return lWeight;
int lMax = Math.Min(mNumChars, Math.Min(aString1.Length, aString2.Length));
int lPos = 0;
while (lPos < lMax && aString1[lPos] == aString2[lPos])
++lPos;
if (lPos == 0) return lWeight;
return lWeight + 0.1 * lPos * (1.0 - lWeight);
}
}
The above code is static class need to implement as array list for that class. Array list must compare as per jaro winkler algorithm. The below code I posting my main class.
class Program
{
static void Main(string[] args)
{
string target;
string[] source1 = new string[]
{
"xyz technology solutions"
};
while (true)
{
Console.Write("Please enter target string: ");
target = Console.ReadLine();
numbersInput.Add(target);
Console.WriteLine("jarowinkler::{0}%", JaroWinklerDistance.proximity(source1[0].ToLower(), target.ToLower()) * 100);
}
}
}}
so i need to implement array list for this code take input from arraylist. Split that list to words. Words compare must compare source and target then it give matching percentage.
You need to provide desired usage example. From what I understood You would like something like:
ArrayList targets = new ArrayList();
targets.Add("word1");
targets.Add("word2");
targets.Add("word3");
double distPercentage = JaroWinklerDistance.meanProximity("sourceWord", targets);
In this case You should just iterate over ArrayList elements and call ".proximity" for each item transformed into string.
By the way, it's better to use
List<string>
instead of ArrayList because You are dealing specifically with strings

Meaning of rational transfer function underlying MATLAB filter or Scipy.signal filter

I have some MATLAB code that filters an input signal using filter:
CUTOFF = 0.05;
FS = 5000;
[b, a] = butter(1, CUTOFF / (FS / 2), 'high');
% b = [0.99996859, -0.99996859]
% a = [1.0, -0.99993717]
dataAfter = filter(b, a, dataBefore);
I'm trying to convert this code to C#. I have already got the butter function to work pretty fast, but now I'm stuck converting the filter function.
I have read the MATLAB filter documentation and Python Scipy.signal filter documentation, but there is a term present in the transfer function definition that I don't understand.
Here is the "rational transfer function" definition from the linked documentation:
b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
Y(z) = _______________________________________ X(z)
a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Correct me if i'm wrong, but z is the current element of input data, and Y(z) is the output?
If the above this is true, what is X(z) in this equation?
I want to understand this to implement it in C#, if there is an equivalent option then please enlighten me.
In the More About section of the matlab docs as you pointed out, they describe:
The input-output description of the filter operation on a vector in the Z-transform domain is a rational transfer function. A rational transfer function is of the form,
b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
Y(z) = _______________________________________ X(z)
a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Rearranging:
Y(z) b[0] + b[1]z^(-1) + ... + b[M]z^(-M)
H(z) = ____ = _______________________________________
X(z) a[0] + a[1]z^(-1) + ... + a[N]z^(-N)
Thus, X(z) is the z-domain transform of the input vector x (seeDigital Filter). It is important to mention that, also in the docs they give an alternate representation of the transfer function as a difference equation
Which lends itself better to be ported into code. One possible implementation in C#, could be (using this answer as reference)
public static double[] Filter(double[] b, double[] a, double[] x)
{
// normalize if a[0] != 1.0. TODO: check if a[0] == 0
if(a[0] != 1.0)
{
a = a.Select(el => el / a[0]).ToArray();
b = b.Select(el => el / a[0]).ToArray();
}
double[] result = new double[x.Length];
result[0] = b[0] * x[0];
for (int i = 1; i < x.Length; i++)
{
result[i] = 0.0;
int j = 0;
if ((i < b.Length) && (j < x.Length))
{
result[i] += (b[i] * x[j]);
}
while(++j <= i)
{
int k = i - j;
if ((k < b.Length) && (j < x.Length))
{
result[i] += b[k] * x[j];
}
if ((k < x.Length) && (j < a.Length))
{
result[i] -= a[j] * result[k];
}
}
}
return result;
}
Driver:
static void Main(string[] args)
{
double[] dataBefore = { 1, 2, 3, 4 };
double[] b = { 0.99996859, -0.99996859 };
double[] a = { 1.0, -0.99993717 };
var dataAfter = Filter(b1, a, dataBefore);
}
Output
Matlab dataAfter = [0.99996859 1.999874351973491 2.999717289867956 3.999497407630634]
CSharp dataAfter = [0.99996859 1.9998743519734905 2.9997172898679563 3.999497407630634]
UPDATE
If the coefficient vectors a and b have a fixed length of 2 the filtering function can be simplified to:
public static double[] Filter(double[] b, double[] a, double[] x)
{
// normalize if a[0] != 1.0. TODO: check if a[0] == 0
if (a[0] != 1.0)
{
a = a.Select(el => el / a[0]).ToArray();
b = b.Select(el => el / a[0]).ToArray();
}
int length = x.Length;
double z = 0.0;
double[] y = new double[length]; // output filtered signal
double b0 = b[0];
double b1 = b[1];
double a1 = a[1];
for (int i = 0; i < length; i++)
{
y[i] = b0 * x[i] + z;
z = b1 * x[i] - a1 * y[i];
}
return y;
}

RSI vs Wilder's RSI Calculation Problems

I am having trouble getting a smoothed RSI. The below picture is from freestockcharts.com. The calculation uses this code.
public static double CalculateRsi(IEnumerable<double> closePrices)
{
var prices = closePrices as double[] ?? closePrices.ToArray();
double sumGain = 0;
double sumLoss = 0;
for (int i = 1; i < prices.Length; i++)
{
var difference = prices[i] - prices[i - 1];
if (difference >= 0)
{
sumGain += difference;
}
else
{
sumLoss -= difference;
}
}
if (sumGain == 0) return 0;
if (Math.Abs(sumLoss) < Tolerance) return 100;
var relativeStrength = sumGain / sumLoss;
return 100.0 - (100.0 / (1 + relativeStrength));
}
https://stackoverflow.com/questions/...th-index-using-some-programming-language-js-c
This seems to be the pure RSI with no smoothing. How does a smoothed RSI get calculated? I have tried changing it to fit the definitions of the these two sites however the output was not correct. It was barely smoothed.
(I don't have enough rep to post links)
tc2000 -> Indicators -> RSI_and_Wilder_s_RSI (Wilder's smoothing = Previous MA value + (1/n periods * (Close - Previous MA)))
priceactionlab -> wilders-cutlers-and-harris-relative-strength-index (RS = EMA(Gain(n), n)/EMA(Loss(n), n))
Can someone actually do the calculation with some sample data?
Wilder's RSI vs RSI
In order to calculate the RSI, you need a period to calculate it with. As noted on Wikipedia, 14 is used quite often.
So the calculation steps would be as follows:
Period 1 - 13, RSI = 0
Period 14:
AverageGain = TotalGain / PeriodCount;
AverageLoss = TotalLoss / PeriodCount;
RS = AverageGain / AverageLoss;
RSI = 100 - 100 / (1 + RS);
Period 15 - to period (N):
if (Period(N)Change > 0
AverageGain(N) = ((AverageGain(N - 1) * (PeriodCount - 1)) + Period(N)Change) / PeriodCount;
else
AverageGain(N) = (AverageGain(N - 1) * (PeriodCount - 1)) / PeriodCount;
if (this.Change < 0)
AverageLoss(N) = ((AverageLoss(N - 1) * (PeriodCount - 1)) + Math.Abs(Period(N)Change)) / PeriodCount;
else
AverageLoss(N) = (AverageLoss(N - 1) * (PeriodCount - 1)) / PeriodCount;
RS = AverageGain / AverageLoss;
RSI = 100 - (100 / (1 + RS));
Thereafter, to smooth the values, you need to apply a moving average of a certain period to your RSI values. To do that, traverse your RSI values from the last index to the first and calculate your average for the current period based on the preceding x smoothing periods.
Once done, just reverse the list of values to get the expected order:
List<double> SmoothedRSI(IEnumerable<double> rsiValues, int smoothingPeriod)
{
if (rsiValues.Count() <= smoothingPeriod)
throw new Exception("Smoothing period too large or too few RSI values passed.");
List<double> results = new List<double>();
List<double> reversedRSIValues = rsiValues.Reverse().ToList();
for (int i = 1; i < reversedRSIValues.Count() - smoothingPeriod - 1; i++)
results.Add(reversedRSIValues.Subset(i, i + smoothingPeriod).Average());
return results.Reverse().ToList();
}
The Subset method is just a simple extension method as follows:
public static List<double> Subset(this List<double> values, int start, int end)
{
List<double> results = new List<double>();
for (int i = start; i <= end; i++)
results.Add(values[i]);
return results;
}
Disclaimer, I did not test the code, but it should give you an idea of how the smoothing is applied.
You can't get accurate values without buffers / global variables to store data.
This is a smoothed indicator, meaning it doesn't only use 14 bars but ALL THE BARS:
Here's a step by step article with working and verified source codes generating exactly the same values if prices and number of available bars are the same, of course (you only need to load the price data from your source):
Tested and verified:
using System;
using System.Data;
using System.Globalization;
namespace YourNameSpace
{
class PriceEngine
{
public static DataTable data;
public static double[] positiveChanges;
public static double[] negativeChanges;
public static double[] averageGain;
public static double[] averageLoss;
public static double[] rsi;
public static double CalculateDifference(double current_price, double previous_price)
{
return current_price - previous_price;
}
public static double CalculatePositiveChange(double difference)
{
return difference > 0 ? difference : 0;
}
public static double CalculateNegativeChange(double difference)
{
return difference < 0 ? difference * -1 : 0;
}
public static void CalculateRSI(int rsi_period, int price_index = 5)
{
for(int i = 0; i < PriceEngine.data.Rows.Count; i++)
{
double current_difference = 0.0;
if (i > 0)
{
double previous_close = Convert.ToDouble(PriceEngine.data.Rows[i-1].Field<string>(price_index));
double current_close = Convert.ToDouble(PriceEngine.data.Rows[i].Field<string>(price_index));
current_difference = CalculateDifference(current_close, previous_close);
}
PriceEngine.positiveChanges[i] = CalculatePositiveChange(current_difference);
PriceEngine.negativeChanges[i] = CalculateNegativeChange(current_difference);
if(i == Math.Max(1,rsi_period))
{
double gain_sum = 0.0;
double loss_sum = 0.0;
for(int x = Math.Max(1,rsi_period); x > 0; x--)
{
gain_sum += PriceEngine.positiveChanges[x];
loss_sum += PriceEngine.negativeChanges[x];
}
PriceEngine.averageGain[i] = gain_sum / Math.Max(1,rsi_period);
PriceEngine.averageLoss[i] = loss_sum / Math.Max(1,rsi_period);
}else if (i > Math.Max(1,rsi_period))
{
PriceEngine.averageGain[i] = ( PriceEngine.averageGain[i-1]*(rsi_period-1) + PriceEngine.positiveChanges[i]) / Math.Max(1, rsi_period);
PriceEngine.averageLoss[i] = ( PriceEngine.averageLoss[i-1]*(rsi_period-1) + PriceEngine.negativeChanges[i]) / Math.Max(1, rsi_period);
PriceEngine.rsi[i] = PriceEngine.averageLoss[i] == 0 ? 100 : PriceEngine.averageGain[i] == 0 ? 0 : Math.Round(100 - (100 / (1 + PriceEngine.averageGain[i] / PriceEngine.averageLoss[i])), 5);
}
}
}
public static void Launch()
{
PriceEngine.data = new DataTable();
//load {date, time, open, high, low, close} values in PriceEngine.data (6th column (index #5) = close price) here
positiveChanges = new double[PriceEngine.data.Rows.Count];
negativeChanges = new double[PriceEngine.data.Rows.Count];
averageGain = new double[PriceEngine.data.Rows.Count];
averageLoss = new double[PriceEngine.data.Rows.Count];
rsi = new double[PriceEngine.data.Rows.Count];
CalculateRSI(14);
}
}
}
For detailed step-by-step instructions, I wrote a lengthy article, you can check it here: https://turmanauli.medium.com/a-step-by-step-guide-for-calculating-reliable-rsi-values-programmatically-a6a604a06b77
P.S. functions only work for simple indicators (Simple Moving Average), even Exponential Moving Average, Average True Range absolutely require global variables to store previous values.

Find the min and max for quadratic equation

how to find the min and max for quadratic equation using c# ??
f(x,y) = x^2 + y^2 + 25 * (sin(x)^2 + sin(y)^2) ,where (x,y) from (-2Pi, 2Pi) ??
in the manual solving I got min is = 0 , max = 8Pi^2 = 78.957 .
I tried to write the code based on liner quadratic code but something goes totally wrong
this code give the min = -4.?? and the max = 96 could you help to know where is my mistake please ??
I uploaded the code to dropbox if anyone can have look : https://www.dropbox.com/s/p7y6krk2gk29i9e/Program.cs
double[] X, Y, Result; // Range array and result array.
private void BtnRun_Click(object sender, EventArgs e)
{
//Set any Range for the function
X = setRange(-2 * Math.PI, 2 * Math.PI, 10000);
Y = setRange(-2 * Math.PI, 2 * Math.PI, 10000);
Result = getOutput_twoVariablesFunction(X, Y);
int MaxIndex = getMaxIndex(Result);
int MinIndex = getMinIndex(Result);
TxtMin.Text = Result[MinIndex].ToString();
TxtMax.Text = Result[MaxIndex].ToString();
}
private double twoVariablesFunction(double x,double y)
{
double f;
//Set any two variables function
f = Math.Pow(x, 2) + Math.Pow(y, 2) + 25 * (Math.Pow(Math.Sin(x), 2) + Math.Pow(Math.Sin(y), 2));
return f;
}
private double[] setRange(double Start, double End, int Sample)
{
double Step = (End - Start) / Sample;
double CurrentVaue = Start;
double[] Array = new double[Sample];
for (int Index = 0; Index < Sample; Index++)
{
Array[Index] = CurrentVaue;
CurrentVaue += Step;
}
return Array;
}
private double[] getOutput_twoVariablesFunction(double[] X, double[] Y)
{
int Step = X.Length;
double[] Array = new double[Step];
for (int Index = 0; Index < X.Length ; Index++)
{
Array[Index] = twoVariablesFunction(X[Index], Y[Index]);
}
return Array;
}
private int getMaxIndex(double[] ValuesArray)
{
double M = ValuesArray.Max();
int Index = ValuesArray.ToList().IndexOf(M);
return Index;
}
private int getMinIndex(double[] ValuesArray)
{
double M = ValuesArray.Min();
int Index = ValuesArray.ToList().IndexOf(M);
return Index;
}
Do you want to compute (sin(x))^2 or sin(x^2)? In your f(x,y) formula it looks like (sin(x))^2, but in your method twoVariablesFunction like sin(x^2).

C# ModInverse Function

Is there a built in function that would allow me to calculate the modular inverse of a(mod n)?
e.g. 19^-1 = 11 (mod 30), in this case the 19^-1 == -11==19;
Since .Net 4.0+ implements BigInteger with a special modular arithmetics function ModPow (which produces “X power Y modulo Z”), you don't need a third-party library to emulate ModInverse. If n is a prime, all you need to do is to compute:
a_inverse = BigInteger.ModPow(a, n - 2, n)
For more details, look in Wikipedia: Modular multiplicative inverse, section Using Euler's theorem, the special case “when m is a prime”. By the way, there is a more recent SO topic on this: 1/BigInteger in c#, with the same approach suggested by CodesInChaos.
int modInverse(int a, int n)
{
int i = n, v = 0, d = 1;
while (a>0) {
int t = i/a, x = a;
a = i % x;
i = x;
x = d;
d = v - t*x;
v = x;
}
v %= n;
if (v<0) v = (v+n)%n;
return v;
}
The BouncyCastle Crypto library has a BigInteger implementation that has most of the modular arithmetic functions. It's in the Org.BouncyCastle.Math namespace.
Here is a slightly more polished version of Samuel Allan's algorithm. The TryModInverse method returns a bool value, that indicates whether a modular multiplicative inverse exists for this number and modulo.
public static bool TryModInverse(int number, int modulo, out int result)
{
if (number < 1) throw new ArgumentOutOfRangeException(nameof(number));
if (modulo < 2) throw new ArgumentOutOfRangeException(nameof(modulo));
int n = number;
int m = modulo, v = 0, d = 1;
while (n > 0)
{
int t = m / n, x = n;
n = m % x;
m = x;
x = d;
d = checked(v - t * x); // Just in case
v = x;
}
result = v % modulo;
if (result < 0) result += modulo;
if ((long)number * result % modulo == 1L) return true;
result = default;
return false;
}
There is no library for getting inverse mod, but the following code can be used to get it.
// Given a and b->ax+by=d
long[] u = { a, 1, 0 };
long[] v = { b, 0, 1 };
long[] w = { 0, 0, 0 };
long temp = 0;
while (v[0] > 0)
{
double t = (u[0] / v[0]);
for (int i = 0; i < 3; i++)
{
w[i] = u[i] - ((int)(Math.Floor(t)) * v[i]);
u[i] = v[i];
v[i] = w[i];
}
}
// u[0] is gcd while u[1] gives x and u[2] gives y.
// if u[1] gives the inverse mod value and if it is negative then the following gives the first positive value
if (u[1] < 0)
{
while (u[1] < 0)
{
temp = u[1] + b;
u[1] = temp;
}
}

Categories

Resources