private static int GetTrack(int min, int max, int count, double val) { val = min + (max - min) * val; var arr = Expendator.Seq(min, max, count); return(Array.IndexOf(arr, Vectors.Create(arr).BinaryApproxSearch(val))); }
/// <summary> /// Возвращает массив точек на окружности /// </summary> /// <param name="args">Углы точек относительно центра окружности и оси X</param> /// <param name="weights">Веса точек (по умолчанию единичные)</param> /// <returns></returns> public Normal2D[] GetNormalsOnCircle(double[] args, double[] weights = null) { weights = weights ?? Vectors.Create(1.0, args.Length).DoubleMas; Normal2D[] res = new Normal2D[args.Length]; for (int i = 0; i < res.Length; i++) { res[i] = new Normal2D(this.center, new Point(center.x + radius * Math.Cos(args[i]), center.y + radius * Math.Sin(args[i])), weights[i]); } return(res); }
/// <summary> /// Возвращает массив равномерно рассположенных по окружности нормалей /// </summary> /// <param name="count"></param> /// <param name="weights"></param> /// <returns></returns> public Normal2D[] GetNormalsOnCircle(int count, double[] weights = null) { double h = 2 * Math.PI / count; weights = weights ?? Vectors.Create(h * radius, count).DoubleMas; double[] args = new double[count]; for (int i = 0; i < count; i++) { args[i] = i * h; } return(GetNormalsOnCircle(args, weights)); }
public static void VectorExamples() { var v = new Vectors(5); v.Show(); // ( 0 0 0 0 0 ) v = new Vectors(5, 1.0); v.Show(); // ( 1 1 1 1 1 ) v = new Vectors(1, 2, 3, 4, 5, 6, 7, 9.5, -2, 3); v.Show(); // ( 1 2 3 4 5 6 7 9,5 -2 3 ) v = new Vectors(new double[] { 1, 2, 3, -3, -2, -1, 0 }); v.Show(); // ( 1 2 3 -3 -2 -1 0 ) v[6].Show(); // 0 v.EuqlidNorm.Show(); // 0,7559289460184545 v.Normalize(0, 1).Show(); // ( 0,6666666666666666 0,8333333333333333 1 0 0,16666666666666666 0,3333333333333333 0,5 ) v.Range.Show(); // 6 v.SubVector(4).Show(); // ( 1 2 3 -3 ) v.Average.Show(); // 1,7142857142857142 v.Contain(3).Show(); // True v.Normalize(-0.5, 0.5).ToRationalStringTab().Show(); // ( 1/6 1/3 1/2 -1/2 -1/3 -1/6 0 ) var p = Vectors.Create(dim: 7, min: 0, max: 2); p.Show(); // ( 1,4585359040647745 1,7510524201206863 1,4706563879735768 0,45403700647875667 0,022686069831252098 1,9943826524540782 0,3851787596940994 ) Vectors.Mix(v, p).Show(); // ( 1 1,4585359040647745 2 1,7510524201206863 3 1,4706563879735768 -3 0,45403700647875667 -2 0,022686069831252098 -1 1,9943826524540782 0 0,3851787596940994 ) (v + p).Show(); // ( 2,4585359040647745 3,7510524201206863 4,470656387973577 -2,5459629935212433 -1,977313930168748 0,9943826524540782 0,3851787596940994 ) (v * p).Show(); // 5,970744096674025 Vectors.CompMult(v, p).Show(); // ( 1,4585359040647745 3,5021048402413726 4,41196916392073 -1,36211101943627 -0,045372139662504196 -1,9943826524540782 0 ) (2.4 * v.AbsVector - p / 2).Sort.BinaryApproxSearch(1.5).Show(); // 1,4028086737729608 }
/// <summary> /// Получить случайный массив упрощённых пчёл /// </summary> /// <param name="f"></param> /// <param name="min"></param> /// <param name="max"></param> /// <param name="count">Число пчёл</param> /// <returns></returns> public static SBee[] Create(Func <Vectors, double> f, Vectors min, Vectors max, int count = 100, bool withaverage = true) { SBee[] res = new SBee[count]; Vectors[] tmp = new Vectors[count]; Parallel.For(0, count, (int i) => { tmp[i] = Vectors.Create(min, max); }); for (int i = 0; i < count; i++) { res[i] = new SBee(tmp[i], f(tmp[i])); } if (withaverage) { res[res.Length - 1] = new SBee((max + min) / 2, f); } return(res); }
/// <summary> /// Cleans scan border noise from the <see cref="Image"/>. /// </summary> /// <param name="maxNoiseWidth">The maximum width of the noise, in inches.</param> /// <param name="maxNoiseHeight">The maximum height of the noise, in inches.</param> /// <returns> /// A new cleaned <see cref="Image"/>. /// </returns> public Image CleanOverscan(float maxNoiseWidth, float maxNoiseHeight) { int width = this.Width; int height = this.Height; int stride1 = this.Stride1; int stride = this.Stride; Image dst = this.Copy(null, true); ulong[] bits = dst.Bits; int maxwidth = (int)((maxNoiseWidth * this.HorizontalResolution) + 0.5f); if (maxwidth > 0) { ClearLeft(FindLeft(maxwidth)); ClearRight(FindRight(maxwidth)); } int maxheight = (int)((maxNoiseHeight * this.VerticalResolution) + 0.5f); if (maxheight > 0) { ClearTop(FindTop(maxheight)); ClearBottom(FindBottom(maxheight)); } return(dst); int[] FindLeft(int maxlen) { int scanlen = Core.MinMax.Min(width, maxlen); int[] lengths = new int[height]; for (int iy = 0, pos = 0; iy < height; iy++, pos += stride1) { int len = BitUtils.BitScanZeroForward(scanlen, bits, pos); lengths[iy] = len == -1 ? 0 : len - pos + 1; } return(lengths); } int[] FindRight(int maxlen) { int scanlen = Core.MinMax.Min(width, maxlen); int[] lengths = new int[height]; for (int iy = 0, pos = width - 1; iy < height; iy++, pos += stride1) { int len = BitUtils.BitScanZeroReverse(scanlen, bits, pos); lengths[iy] = len == -1 ? 0 : pos - len + 1; } return(lengths); } int[] FindTop(int maxlen) { int scanlen = Core.MinMax.Min(height, maxlen); int[] lengths = Vectors.Create(width, scanlen); for (int ix = 0; ix < width; ix++) { ulong mask = BitUtils.SetBit(0ul, ix & 63); for (int iy = 0, off = ix >> 6; iy < scanlen; iy++, off += stride) { if ((bits[off] & mask) == 0) { lengths[ix] = iy; break; } } } return(lengths); } int[] FindBottom(int maxlen) { int scanlen = Core.MinMax.Min(height, maxlen); int[] lengths = Vectors.Create(width, scanlen); int size = stride * height; for (int ix = 0; ix < width; ix++) { ulong mask = BitUtils.SetBit(0ul, ix & 63); for (int iy = 0, off = size - stride + (ix >> 6); iy < scanlen; iy++, off -= stride) { if ((bits[off] & mask) == 0) { lengths[ix] = iy; break; } } } return(lengths); } void ClearLeft(int[] lengths) { for (int iy = 0, off = 0; iy < height; iy++, off += stride1) { int len = lengths[iy]; if (len != 0) { BitUtils.ResetBits(len, bits, off); } } } void ClearRight(int[] lengths) { for (int iy = 0, off = width; iy < height; iy++, off += stride1) { int len = lengths[iy]; if (len != 0) { BitUtils.ResetBits(len, bits, off - len); } } } void ClearTop(int[] lengths) { for (int ix = 0; ix < width; ix++) { int len = lengths[ix]; if (len != 0) { ulong mask = ~BitUtils.SetBit(0ul, ix & 63); Vectors.AndC(len, mask, bits, ix >> 6, stride); } } } void ClearBottom(int[] lengths) { int size = stride * height; for (int ix = 0; ix < width; ix++) { int len = lengths[ix]; if (len != 0) { ulong mask = ~BitUtils.SetBit(0ul, ix & 63); Vectors.AndC(len, mask, bits, size - (len * stride) + (ix >> 6), stride); } } } }
/// <summary> /// Сделать шаг по алгоритму пчелиной колонии /// </summary> /// <param name="mas"></param> /// <param name="f"></param> /// <param name="min"></param> /// <param name="max"></param> /// <param name="n"></param> /// <param name="p"></param> /// <param name="e"></param> /// <param name="sp"></param> /// <param name="se"></param> /// <param name="delta"></param> public static void MakeStep(ref SBee[] mas, Func <Vectors, double> f, Vectors min, Vectors max, int n = 1, int p = 300, int e = 100, int sp = 50, int se = 100, double delta = 1.0) { Array.Sort(mas); Vectors[] t = new Vectors[se]; for (int i = 0; i < e; i++) { SBee it = new SBee(mas[i]), tmp; Vectors cent = it.x.dup; Parallel.For(0, t.Length, (int u) => { t[u] = Vectors.Create(cent, delta); }); for (int j = 0; j < se; j++) { tmp = new SBee(t[j], f); if (tmp.v < it.v) { it = new SBee(tmp); } } mas[i] = new SBee(it); } t = new Vectors[sp]; for (int i = e; i < p; i++) { SBee it = new SBee(mas[i]), tmp; Vectors cent = it.x.dup; Parallel.For(0, t.Length, (int u) => { t[u] = Vectors.Create(cent, delta); }); for (int j = 0; j < sp; j++) { tmp = new SBee(t[j], f); if (tmp.v < it.v) { it = new SBee(tmp); } } mas[i] = new SBee(it); } t = new Vectors[mas.Length - p]; Parallel.For(0, t.Length, (int i) => { t[i] = Vectors.Create(min, max); }); for (int i = p; i < mas.Length; i++) { mas[i] = new SBee(t[i - p], f); } }
/// <inheritdoc /> /// <exception cref="ArgumentNullException"> /// <para><paramref name="x"/> is <b>null</b>.</para> /// <para>-or-</para> /// <para><paramref name="y"/> is <b>null</b>.</para> /// </exception> /// <exception cref="ArgumentException"> /// <para>The number of elements in <paramref name="y"/> does not match the number of elements in <paramref name="x"/>.</para> /// <para>-or-</para> /// <para><paramref name="weights"/> is not <b>null</b> and the number of elements in <paramref name="weights"/> does not match the number of elements in <paramref name="x"/>.</para> /// </exception> public SupportVectorMachine Learn( IList <float[]> x, IList <bool> y, IList <float> weights, CancellationToken cancellationToken) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } if (y.Count != x.Count) { throw new ArgumentException("The number of output labels must match the number of input vectors.", nameof(y)); } if (weights != null && weights.Count != x.Count) { throw new ArgumentException("The number of weights must match the number of input vectors.", nameof(weights)); } int sampleCount = x.Count; // count positive and negative labels Labels.GetRatio(y, out int positives, out int negatives); // if all labels are either positive or negative // create machine that will always produce one kind of output if (positives == 0 || negatives == 0) { return(new SupportVectorMachine( this.kernel, new float[0][], new float[0], positives == 0 ? -1 : 1)); } // create expected values (+/-1) int[] expected = new int[sampleCount]; for (int i = 0; i < sampleCount; i++) { expected[i] = y[i] ? 1 : -1; } // calculate complexity float positiveComplexity = this.Complexity * this.PositiveWeight; float negativeComplexity = this.Complexity * this.NegativeWeight; // calculate costs associated with each input float[] c = new float[sampleCount]; for (int i = 0; i < sampleCount; i++) { c[i] = y[i] ? positiveComplexity : negativeComplexity; } if (weights != null) { for (int i = 0; i < sampleCount; i++) { c[i] *= weights[i]; } } switch (this.Algorithm) { case SMOAlgorithm.LibSVM: Func <int, int[], int, float[], float[]> q = (int i, int[] indices, int length, float[] result) => { for (int j = 0; j < length; j++) { result[j] = expected[i] * expected[indices[j]] * this.kernel.Execute(x[i].Length, x[i], 0, x[indices[j]], 0); } return(result); }; LibSVMOptimization s = new LibSVMOptimization() { Tolerance = this.Tolerance, }; s.Optimize( sampleCount, c, Vectors.Create(sampleCount, -1.0f), expected, q, out float[] solution, out float rho); /*HashSet<int> activeExamples = new HashSet<int>(); * for (int i = 0; i < solution.Length; i++) * { * if (solution[i] > 0) * { * activeExamples.Add(i); * } * } * * float b_lower = rho; * float b_upper = rho; * * float[][] vectors = new float[activeExamples.Count][]; * float[] weights = new float[activeExamples.Count]; * * int index = 0; * foreach (var j in activeExamples) * { * vectors[index] = samples[j].x.ToArray(); * weights[index] = solution[j] * y[j]; * index++; * } * * return new SupportVectorMachine( * this.kernel, * vectors, * weights, * -(b_lower + b_upper) / 2);*/ return(CreateMachine(solution, -rho)); default: throw new ArgumentException("The SMO optimization algorithm is invalid."); } SupportVectorMachine CreateMachine(float[] alphas, float bias) { // count number of non-bound support vectors int count = 0; for (int i = 0; i < alphas.Length; i++) { if (alphas[i] > 0) { count++; } } // create support vectors and weights float[][] v = new float[count][]; float[] w = new float[count]; for (int i = 0, j = 0; i < alphas.Length; i++) { if (alphas[i] > 0) { v[j] = x[i].ToArray(); w[j] = alphas[i] * expected[i]; j++; } } return(new SupportVectorMachine(this.kernel, v, w, bias)); } }