2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-09-13 20:43:19 +00:00
This commit is contained in:
2022-11-05 17:48:30 +03:00
parent e83f51f952
commit f1d5b0a38b
12 changed files with 746 additions and 54 deletions

View File

@@ -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];
}
}

View 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();
}
}
}

View File

@@ -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>

View 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;
}
}
}

View File

@@ -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)