mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 11:32:59 +00:00
Analysis
This commit is contained in:
parent
8e17a5b677
commit
6537913b11
13
Esiur.Analysis/Esiur.Analysis.csproj
Normal file
13
Esiur.Analysis/Esiur.Analysis.csproj
Normal file
@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Signals\Modulation\" />
|
||||
<Folder Include="Optimization\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
69
Esiur.Analysis/Signals/Capacity.cs
Normal file
69
Esiur.Analysis/Signals/Capacity.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using Esiur.Analysis.Statistics;
|
||||
using Esiur.Analysis.Units;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Signals
|
||||
{
|
||||
public static class Capacity
|
||||
{
|
||||
public struct CSI
|
||||
{
|
||||
public double SNR;
|
||||
public Probability Probability;
|
||||
|
||||
public CSI(double snr, double probability)
|
||||
{
|
||||
SNR = snr;
|
||||
Probability = probability;
|
||||
}
|
||||
}
|
||||
|
||||
public struct OutageCapacity
|
||||
{
|
||||
public BitRate Capacity;
|
||||
public double MinSNR;
|
||||
public Probability Outage;
|
||||
public double Bandwidth;
|
||||
|
||||
public OutageCapacity(Probability outage, double minSNR, double bandwidth)
|
||||
{
|
||||
MinSNR = minSNR;
|
||||
Outage = outage;
|
||||
Bandwidth = bandwidth;
|
||||
Capacity = (1 - Outage) * bandwidth * Math.Log(1 + minSNR, 2);
|
||||
}
|
||||
|
||||
public override string ToString() => $" {MinSNR.ToString("F")} <{Outage}> => {Capacity}";
|
||||
}
|
||||
|
||||
public static double Compute(double bandwidth, double snr)
|
||||
=> bandwidth * Math.Log(1 + snr, 2);
|
||||
|
||||
|
||||
public static double ComputeErgodic(double bandwidth, CSI[] receiverCSI)
|
||||
{
|
||||
return bandwidth * receiverCSI.Sum(x => Math.Log(1 + x.SNR, 2) * x.Probability);
|
||||
}
|
||||
|
||||
public static OutageCapacity[] ComputeOutage(double bandwidth, CSI[] receiverCSI)
|
||||
{
|
||||
var sorted = receiverCSI.OrderBy(x => x.SNR);
|
||||
var rt = sorted.Select(x => {
|
||||
var pOut = receiverCSI.Where(csi => csi.SNR < x.SNR).Sum(x => x.Probability);
|
||||
return new OutageCapacity()
|
||||
{
|
||||
Outage = pOut,
|
||||
MinSNR = x.SNR,
|
||||
Capacity = (1 - pOut) * bandwidth * Math.Log(1 + x.SNR, 2)
|
||||
};
|
||||
});
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
55
Esiur.Analysis/Signals/DSP.cs
Normal file
55
Esiur.Analysis/Signals/DSP.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Signals
|
||||
{
|
||||
public static class DSP
|
||||
{
|
||||
public static double[] ConvolveMany(params double[][] signals)
|
||||
{
|
||||
var rt = signals[0];
|
||||
|
||||
for (var i = 1; i < signals.Length; i++)
|
||||
rt = rt.Convolve(signals[i]);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static double[] Convolve(this double[] signal, double[] filter)
|
||||
{
|
||||
var length = signal.Length + filter.Length - 1;
|
||||
var rt = new double[length];
|
||||
|
||||
//for (var i = 0; i < signal.Length; i++)
|
||||
// for (var j = 0; j < filter.Length; j++)
|
||||
// rt[i + j] += signal[i] * filter[j];
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
for (var j = 0; j < signal.Length && i - j >= 0 && i - j < filter.Length; j++)
|
||||
{
|
||||
rt[i] = signal[j] * filter[i - j];
|
||||
}
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static double[] CrossCorrelate(this double[] signal, double[] filter)
|
||||
{
|
||||
var length = signal.Length + filter.Length - 1;
|
||||
var rt = new double[length];
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
for (var j = 0; j < signal.Length && j + i < filter.Length; j++)
|
||||
{
|
||||
rt[i] = signal[j] * filter[i + j];
|
||||
}
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
16
Esiur.Analysis/Signals/Propagation.cs
Normal file
16
Esiur.Analysis/Signals/Propagation.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Signals
|
||||
{
|
||||
public static class Propagation
|
||||
{
|
||||
public static readonly double LightSpeed = 2.99792458e8;
|
||||
public static double FindReceivedPower(double transmittedPower, double distance,
|
||||
double transmitterGain, double receiverGain, double pathLoss)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
31
Esiur.Analysis/Statistics/Probability.cs
Normal file
31
Esiur.Analysis/Statistics/Probability.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Esiur.Analysis.Units;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Statistics
|
||||
{
|
||||
public struct Probability
|
||||
{
|
||||
public double Value;
|
||||
|
||||
public static implicit operator Probability(double v) => new Probability(v);
|
||||
public static implicit operator double(Probability v) => v.Value;
|
||||
|
||||
public Probability(double value)
|
||||
{
|
||||
if (value > 1 || value < 0)
|
||||
throw new Exception("0 >= Probability <= 1");
|
||||
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public double ToPercentage() => Value * 100;
|
||||
public Probability FromPercentage(double value) => new Probability(value / 100);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return (Math.Round(Value * 10000) / 100) + "%";
|
||||
}
|
||||
}
|
||||
}
|
44
Esiur.Analysis/Statistics/StatisticalFunctions.cs
Normal file
44
Esiur.Analysis/Statistics/StatisticalFunctions.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Statistics
|
||||
{
|
||||
public static class Statistics
|
||||
{
|
||||
public static double Mean(this double[] values) => values.Sum() / values.Length;
|
||||
|
||||
public static double Variance(this double[] x)
|
||||
{
|
||||
var mean = x.Mean();
|
||||
return x.Sum(x => Math.Pow(x - mean, 2)) / x.Length;
|
||||
}
|
||||
|
||||
|
||||
public static double StdDiv(this double[] x) => Math.Sqrt(x.Variance());
|
||||
|
||||
public static double Covariance(this double[] x, double[] y)
|
||||
{
|
||||
var n = x.Length < y.Length ? x.Length : y.Length;
|
||||
var X = x.Mean();
|
||||
var Y = y.Mean();
|
||||
|
||||
double rt = 0;
|
||||
|
||||
for (var i = 0; i < n; i++)
|
||||
rt += (x[i] - X) * (y[i] - Y);
|
||||
|
||||
return rt / n;
|
||||
}
|
||||
|
||||
|
||||
public static double RMS(this double[] x) => Math.Sqrt(x.Sum(x => x * x) / x.Length);
|
||||
|
||||
|
||||
public static double Correlation(this double[] x, double[] y)
|
||||
{
|
||||
return x.Covariance(y) / (x.StdDiv() * y.StdDiv());
|
||||
}
|
||||
}
|
||||
}
|
81
Esiur.Analysis/Units/BitRate.cs
Normal file
81
Esiur.Analysis/Units/BitRate.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Units
|
||||
{
|
||||
public enum BitRateKind
|
||||
{
|
||||
Bits,
|
||||
Octets,
|
||||
Bytes
|
||||
}
|
||||
|
||||
public struct BitRate : IComparable
|
||||
{
|
||||
public double Value;
|
||||
|
||||
|
||||
public BitRate(double value, BitRateKind kind = BitRateKind.Bits)
|
||||
{
|
||||
if (kind == BitRateKind.Bytes)
|
||||
Value = value * 8;
|
||||
else if (kind == BitRateKind.Octets)
|
||||
Value = value * 7;
|
||||
else
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public static implicit operator BitRate(double d) => new BitRate(d);
|
||||
public static implicit operator double(BitRate d) => d.Value;
|
||||
|
||||
//public static explicit operator PowerUnit(double d) => new PowerUnit(d, PowerUnitKind.Watt);
|
||||
//public static explicit operator double(PowerUnit d) => d.Value;
|
||||
|
||||
//public static PowerUnit operator +(PowerUnit a) => a;
|
||||
//public static PowerUnit operator -(PowerUnit a) => new PowerUnit(-a.num, a.den);
|
||||
|
||||
public static BitRate operator +(BitRate a, BitRate b)
|
||||
=> new BitRate(a.Value + b.Value);
|
||||
|
||||
public static BitRate operator -(BitRate a, BitRate b)
|
||||
=> new BitRate(a.Value - b.Value);
|
||||
|
||||
public static BitRate operator *(BitRate a, BitRate b)
|
||||
=> new BitRate(a.Value * b.Value);
|
||||
|
||||
public static BitRate operator /(BitRate a, BitRate b)
|
||||
{
|
||||
if (b.Value == 0)
|
||||
{
|
||||
throw new DivideByZeroException();
|
||||
}
|
||||
return new BitRate(a.Value / b.Value);
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value >= 1e12)
|
||||
return (Value / 1e12).ToString("F") + " tbps";
|
||||
else if (Value >= 1e9)
|
||||
return (Value / 1e9).ToString("F") + " gbps";
|
||||
else if (Value >= 1e6)
|
||||
return (Value / 1e6).ToString("F") + " mbps";
|
||||
else if (Value >= 1e3)
|
||||
return (Value * 1e3).ToString("F") + " kbps";
|
||||
else
|
||||
return Value.ToString("F") + " bps";
|
||||
}
|
||||
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is BitRate p)
|
||||
return Value.CompareTo(p.Value);
|
||||
else
|
||||
return Value.CompareTo(obj);
|
||||
}
|
||||
}
|
||||
}
|
81
Esiur.Analysis/Units/PowerUnit.cs
Normal file
81
Esiur.Analysis/Units/PowerUnit.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Analysis.Units
|
||||
{
|
||||
public enum PowerUnitKind
|
||||
{
|
||||
Watt,
|
||||
Decibel
|
||||
}
|
||||
|
||||
public struct PowerUnit : IComparable
|
||||
{
|
||||
public double Value;
|
||||
|
||||
|
||||
public PowerUnit(double value, PowerUnitKind kind = PowerUnitKind.Watt)
|
||||
{
|
||||
if (kind == PowerUnitKind.Watt)
|
||||
Value = value;
|
||||
else if (kind == PowerUnitKind.Decibel)
|
||||
Value = FromDb(value);
|
||||
else
|
||||
Value = 0;
|
||||
}
|
||||
|
||||
public static implicit operator PowerUnit(double d) => new PowerUnit(d, PowerUnitKind.Watt);
|
||||
public static implicit operator double(PowerUnit d) => d.Value;
|
||||
|
||||
//public static explicit operator PowerUnit(double d) => new PowerUnit(d, PowerUnitKind.Watt);
|
||||
//public static explicit operator double(PowerUnit d) => d.Value;
|
||||
|
||||
//public static PowerUnit operator +(PowerUnit a) => a;
|
||||
//public static PowerUnit operator -(PowerUnit a) => new PowerUnit(-a.num, a.den);
|
||||
|
||||
public static PowerUnit operator +(PowerUnit a, PowerUnit b)
|
||||
=> new PowerUnit(a.Value + b.Value);
|
||||
|
||||
public static PowerUnit operator -(PowerUnit a, PowerUnit b)
|
||||
=> new PowerUnit(a.Value - b.Value);
|
||||
|
||||
public static PowerUnit operator *(PowerUnit a, PowerUnit b)
|
||||
=> new PowerUnit(a.Value * b.Value);
|
||||
|
||||
public static PowerUnit operator /(PowerUnit a, PowerUnit b)
|
||||
{
|
||||
if (b.Value == 0)
|
||||
{
|
||||
throw new DivideByZeroException();
|
||||
}
|
||||
return new PowerUnit(a.Value / b.Value);
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value < 1e-6)
|
||||
return (Value * 1e9).ToString("F") + "nW";
|
||||
else if (Value < 1e-3)
|
||||
return (Value * 1e6).ToString("F") + "µW";
|
||||
else if (Value < 1)
|
||||
return (Value * 1e3).ToString("F") + "mW";
|
||||
else
|
||||
return Value.ToString("F") + "W";
|
||||
}
|
||||
|
||||
public double ToDb() => 10 * Math.Log(10, Value);
|
||||
public static double FromDb(double value) => Math.Pow(10, value / 10);
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
|
||||
if (obj is PowerUnit p)
|
||||
return Value.CompareTo(p.Value);
|
||||
else
|
||||
return Value.CompareTo(obj);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esiur.Stores.EntityCore", "
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{331F82B6-6B90-4533-9718-F7C8090D8F19}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Esiur.Analysis", "Esiur.Analysis\Esiur.Analysis.csproj", "{8D52DEEA-B7E8-4C93-9B6C-EDB9C2D25211}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -32,6 +34,10 @@ Global
|
||||
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D52DEEA-B7E8-4C93-9B6C-EDB9C2D25211}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D52DEEA-B7E8-4C93-9B6C-EDB9C2D25211}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D52DEEA-B7E8-4C93-9B6C-EDB9C2D25211}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D52DEEA-B7E8-4C93-9B6C-EDB9C2D25211}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -7,5 +7,7 @@ public interface IUserType
|
||||
{
|
||||
object Get();
|
||||
void Set(object value);
|
||||
|
||||
object SetAndGet(object value);
|
||||
}
|
||||
|
||||
|
103
Esiur/Data/VarList.cs
Normal file
103
Esiur/Data/VarList.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using Esiur.Core;
|
||||
using Esiur.Resource;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public class VarList<T> : IEnumerable<T>, ICollection, ICollection<T>
|
||||
{
|
||||
string propertyName;
|
||||
IResource resource;
|
||||
|
||||
List<T> list = new List<T>();
|
||||
|
||||
public VarList(IResource resource, [CallerMemberName] string propertyName = "")
|
||||
{
|
||||
this.resource = resource;
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
public int Count => list.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public bool IsSynchronized => true;
|
||||
|
||||
|
||||
public object SyncRoot { get; } = new object();
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
list.Add(item);
|
||||
|
||||
resource?.Instance?.Modified(propertyName);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
list.Clear();
|
||||
resource?.Instance?.Modified(propertyName);
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return list.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
list.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
(list as ICollection).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
if ( list.Remove(item))
|
||||
{
|
||||
resource?.Instance?.Modified(propertyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return list[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
//var oldValue = list[index];
|
||||
|
||||
lock (SyncRoot)
|
||||
list[index] = value;
|
||||
|
||||
resource?.Instance?.Modified(propertyName);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
<Copyright>Ahmed Kh. Zamil</Copyright>
|
||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Version>2.3.6</Version>
|
||||
<Version>2.3.7</Version>
|
||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
||||
<Authors>Ahmed Kh. Zamil</Authors>
|
||||
<AssemblyVersion></AssemblyVersion>
|
||||
|
@ -45,6 +45,8 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Esiur.Analysis.Signals;
|
||||
using Esiur.Analysis.Units;
|
||||
|
||||
namespace Test
|
||||
{
|
||||
@ -54,6 +56,17 @@ namespace Test
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
|
||||
|
||||
var outage = Capacity.ComputeOutage(20000000, new Capacity.CSI[]
|
||||
{
|
||||
new Capacity.CSI(PowerUnit.FromDb(20), 0.1),
|
||||
new Capacity.CSI(PowerUnit.FromDb(15), 0.15),
|
||||
new Capacity.CSI(PowerUnit.FromDb(10), 0.25),
|
||||
new Capacity.CSI(PowerUnit.FromDb(5), 0.25),
|
||||
new Capacity.CSI(PowerUnit.FromDb(0), 0.15),
|
||||
new Capacity.CSI(PowerUnit.FromDb(-5), 0.1),
|
||||
});
|
||||
|
||||
// Create stores to keep objects.
|
||||
var system = await Warehouse.Put("sys", new MemoryStore());
|
||||
var server = await Warehouse.Put("sys/server", new DistributedServer());
|
||||
|
@ -6,6 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Esiur.Analysis\Esiur.Analysis.csproj" />
|
||||
<ProjectReference Include="..\Esiur\Esiur.csproj" OutputItemType="Analyzer" />
|
||||
</ItemGroup>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user