mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-09-13 20:43:19 +00:00
Genetic
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Signals
|
||||
namespace Esiur.Analysis.DSP
|
||||
{
|
||||
public static class DSP
|
||||
public static class Functions
|
||||
{
|
||||
public static double[] ConvolveMany(params double[][] signals)
|
||||
{
|
||||
@@ -27,9 +27,11 @@ namespace Esiur.Analysis.Signals
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
for (var j = 0; j < signal.Length && i - j >= 0 && i - j < filter.Length; j++)
|
||||
|
||||
for (var j = 0; j < signal.Length; j++)
|
||||
{
|
||||
rt[i] = signal[j] * filter[i - j];
|
||||
if (i - j >= 0 && i - j < filter.Length)
|
||||
rt[i] += signal[j] * filter[i - j];
|
||||
}
|
||||
}
|
||||
|
73
Esiur.Analysis/DSP/TransferFunction.cs
Normal file
73
Esiur.Analysis/DSP/TransferFunction.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Xml.Schema;
|
||||
|
||||
namespace Esiur.Analysis.DSP
|
||||
{
|
||||
public class TransferFunction
|
||||
{
|
||||
|
||||
public double Step { get; set; }
|
||||
|
||||
double[] inputs;
|
||||
double[] outputs;
|
||||
|
||||
public double[] InputCoefficients { get; set; }
|
||||
public double[] OutputCoefficients { get; set; }
|
||||
|
||||
public TransferFunction(double[] numerator, double[] denominator, double step = 0.01)
|
||||
{
|
||||
inputs = new double[numerator.Length];
|
||||
outputs = new double[denominator.Length];
|
||||
|
||||
InputCoefficients = numerator.Reverse().ToArray();
|
||||
OutputCoefficients = denominator.Reverse().ToArray();
|
||||
|
||||
Step = step;
|
||||
}
|
||||
|
||||
public double Evaluate(double value)
|
||||
{
|
||||
var xs = new double[inputs.Length];
|
||||
xs[0] = value;// * InputCoefficients.Last();
|
||||
|
||||
|
||||
// diffrentiate
|
||||
for(var i = 1; i < xs.Length; i++)
|
||||
xs[i] = (xs[i - 1] - inputs[i - 1]) / Step;
|
||||
|
||||
var ys = new double[outputs.Length];
|
||||
|
||||
// integrate
|
||||
for (var i = outputs.Length - 2; i >= 0; i--)
|
||||
{
|
||||
var iy = outputs[i] + (Step * outputs[i + 1]);
|
||||
if (double.IsNaN(iy) || double.IsInfinity(iy))
|
||||
ys[i] = outputs[i];
|
||||
else
|
||||
ys[i] = iy;
|
||||
}
|
||||
|
||||
var v = xs.Zip(InputCoefficients, (x, c) => x * c).Sum() - ys.Zip(OutputCoefficients, (y, c) => y * c).Sum();
|
||||
|
||||
if (double.IsNaN(v) || double.IsInfinity(v))
|
||||
ys[ys.Length - 1] = outputs[ys.Length - 1];
|
||||
else
|
||||
ys[ys.Length - 1] = v;
|
||||
|
||||
inputs = xs;
|
||||
outputs = ys;
|
||||
|
||||
return ys[0];
|
||||
}
|
||||
|
||||
public double[] Evaluate(double[] value)
|
||||
{
|
||||
return value.Select(x => Evaluate(x)).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -12,11 +13,14 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Processing\" />
|
||||
<Folder Include="Signals\Modulation\" />
|
||||
<Folder Include="Optimization\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Fuzzy\FuzzyRule.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Esiur\Esiur.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
135
Esiur.Analysis/Optimization/Genetic.cs
Normal file
135
Esiur.Analysis/Optimization/Genetic.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using Esiur.Data;
|
||||
using Esiur.Resource;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Optimization
|
||||
{
|
||||
public class Genetic<T> where T : unmanaged
|
||||
{
|
||||
|
||||
Random rand = new Random();
|
||||
|
||||
public static unsafe byte[] Encode(in T value)
|
||||
{
|
||||
byte[] result = new byte[sizeof(T)];
|
||||
fixed (byte* dst = result)
|
||||
*(T*)dst = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static unsafe T Decode(byte[] data)
|
||||
{
|
||||
fixed (byte* src = data)
|
||||
return *(T*)src;
|
||||
}
|
||||
|
||||
public List<T> Population = new List<T>();
|
||||
|
||||
public int PopulationSize { get; set; }
|
||||
private int DataSize { get; set; }
|
||||
|
||||
public Func<T, double> FitnessFunction { get; set; }
|
||||
|
||||
public unsafe Genetic(int populationSize, Func<T, double> fitnessFunction)
|
||||
{
|
||||
FitnessFunction = fitnessFunction;
|
||||
PopulationSize = populationSize;
|
||||
DataSize = sizeof(T);
|
||||
}
|
||||
|
||||
void GeneratePopultation()
|
||||
{
|
||||
for (var i = 0; i < PopulationSize; i++)
|
||||
{
|
||||
byte[] buffer = new byte[DataSize];
|
||||
rand.NextBytes(buffer);
|
||||
var record = Decode(buffer);
|
||||
Population.Add(record);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KeyValuePair<T, double>[] GetFitness()
|
||||
{
|
||||
var rt = new List<KeyValuePair<T, double>>();
|
||||
|
||||
foreach (var record in Population)
|
||||
rt.Add(new KeyValuePair<T, double>( record, FitnessFunction(record)));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
T Mate(T parent1, T parent2)
|
||||
{
|
||||
var dp1 = Encode(parent1);
|
||||
var dp2 = Encode(parent2);
|
||||
|
||||
var dc = new byte[dp1.Length];
|
||||
|
||||
|
||||
for (var i = 0; i < dc.Length; i++)
|
||||
{
|
||||
var prop = rand.NextDouble();
|
||||
if (prop < 0.45)
|
||||
dc[i] = dp1[i];
|
||||
else if (prop < 0.9)
|
||||
dc[i] = dp2[i];
|
||||
else
|
||||
dc[i] = (byte)rand.Next(0, 255);
|
||||
}
|
||||
|
||||
return Decode(dc);
|
||||
|
||||
}
|
||||
|
||||
public T Evaluate(int maxIterations)
|
||||
{
|
||||
GeneratePopultation();
|
||||
|
||||
var generation = 0;
|
||||
|
||||
T best;
|
||||
|
||||
do
|
||||
{
|
||||
var ordered = GetFitness().OrderBy(x => x.Value).ToArray();
|
||||
|
||||
best = ordered[0].Key;
|
||||
|
||||
if (ordered[0].Value == 0)
|
||||
break;
|
||||
|
||||
// Elitism selection ( 10% of fittest population )
|
||||
|
||||
var eliteCount = (int)(ordered.Length * 0.1);
|
||||
var neededCount = (int)(ordered.Length * 0.9);
|
||||
|
||||
var newGeneration = ordered.Select(x => x.Key).Take(eliteCount).ToList();
|
||||
|
||||
for (var i = 0; i < neededCount; i++)
|
||||
{
|
||||
var p1 = Population[rand.Next(0, PopulationSize / 2)];
|
||||
var p2 = Population[rand.Next(0, PopulationSize / 2)];
|
||||
|
||||
var offspring = Mate(p1, p2);
|
||||
newGeneration.Add(offspring);
|
||||
}
|
||||
|
||||
Population = newGeneration;
|
||||
|
||||
Debug.WriteLine($"Gen {generation} Fittest: {ordered.First().Value} {ordered.First().Key.ToString()} ");
|
||||
} while (generation++ < maxIterations);
|
||||
|
||||
Debug.WriteLine($"Gen {generation} Best: {best.ToString()} ");
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -33,7 +33,13 @@ namespace Esiur.Analysis.Statistics
|
||||
}
|
||||
|
||||
|
||||
public static double RMS(this double[] x) => Math.Sqrt(x.Sum(x => x * x) / x.Length);
|
||||
public static double RMS(this double[] x)
|
||||
{
|
||||
var r = Math.Sqrt(x.Sum(x => x * x) / x.Length);
|
||||
if (double.IsNaN(r))
|
||||
Console.WriteLine();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public static double Correlation(this double[] x, double[] y)
|
||||
|
Reference in New Issue
Block a user