Skip to content

Commit

Permalink
Removed dependency on C5 package to clean up references on install
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Whitten committed Jun 6, 2024
1 parent 4a376b3 commit 3e35430
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 85 deletions.
79 changes: 79 additions & 0 deletions Source/MicrowaveNetworks/Internal/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,84 @@ public static Type ToNetworkParameterMatrixType(this ParameterType p)
_ => throw new NotImplementedException($"Support for parameter type {p} has not been implemented."),
};
}


#region IList<T> Binary Helpers

// Below copied from https://stackoverflow.com/a/2948872

/// <summary>
/// Performs a binary search on the specified collection.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
/// <typeparam name="TSearch">The type of the searched item.</typeparam>
/// <param name="list">The list to be searched.</param>
/// <param name="value">The value to search for.</param>
/// <param name="comparer">The comparer that is used to compare the value
/// with the list items.</param>
/// <returns></returns>
public static int BinarySearch<TItem, TSearch>(this IList<TItem> list,
TSearch value, Func<TSearch, TItem, int> comparer)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
if (comparer == null)
{
throw new ArgumentNullException("comparer");
}

int lower = 0;
int upper = list.Count - 1;

while (lower <= upper)
{
int middle = lower + (upper - lower) / 2;
int comparisonResult = comparer(value, list[middle]);
if (comparisonResult < 0)
{
upper = middle - 1;
}
else if (comparisonResult > 0)
{
lower = middle + 1;
}
else
{
return middle;
}
}

return ~lower;
}

/// <summary>
/// Performs a binary search on the specified collection.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
/// <param name="list">The list to be searched.</param>
/// <param name="value">The value to search for.</param>
/// <returns></returns>
public static int BinarySearch<TItem>(this IList<TItem> list, TItem value)
{
return BinarySearch(list, value, Comparer<TItem>.Default);
}

/// <summary>
/// Performs a binary search on the specified collection.
/// </summary>
/// <typeparam name="TItem">The type of the item.</typeparam>
/// <param name="list">The list to be searched.</param>
/// <param name="value">The value to search for.</param>
/// <param name="comparer">The comparer that is used to compare the value
/// with the list items.</param>
/// <returns></returns>
public static int BinarySearch<TItem>(this IList<TItem> list, TItem value,
IComparer<TItem> comparer)
{
return list.BinarySearch(value, comparer.Compare);
}
#endregion
}
}
9 changes: 1 addition & 8 deletions Source/MicrowaveNetworks/MicrowaveNetworks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<RepositoryUrl>https://github.com/mdwhitten/microwave-networks</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/mdwhitten/microwave-networks</PackageProjectUrl>
<DocumentationFile>bin\MicrowaveNetworks.xml</DocumentationFile>
Expand All @@ -17,7 +17,6 @@
<Description>A library implementing common tools for working with microwave networks including reading/writing to Touchstone (.snp) files, de/embedding network parameters, etc.</Description>
<Copyright>Copyright © 2021</Copyright>
<Product>Microwave Networks</Product>
<Company>NI</Company>
<GenerateAssemblyCompanyAttribute>True</GenerateAssemblyCompanyAttribute>
</PropertyGroup>
<PropertyGroup>
Expand All @@ -32,7 +31,6 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="C5" Version="2.5.3" />
<PackageReference Include="MathNet.Numerics">
<Version>4.15.0</Version>
</PackageReference>
Expand All @@ -41,11 +39,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces">
<Version>5.0.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472' Or '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces">
<Version>5.0.0</Version>
Expand Down
121 changes: 59 additions & 62 deletions Source/MicrowaveNetworks/NetworkParametersCollection.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System;
using System.Linq;
using System.Collections;
using SCG = System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using C5;
using MathNet.Numerics.Interpolation;
using MicrowaveNetworks.Matrices;
using MicrowaveNetworks.Touchstone.IO;
Expand Down Expand Up @@ -35,12 +33,12 @@ public FrequencyParametersPair(double frequency, NetworkParametersMatrix paramet
Parameters = parameters;
}

/// <summary>Creates a <see cref="FrequencyParametersPair"/> from a <see cref="SCG.KeyValuePair{TKey, TValue}"/> object.</summary>
public static implicit operator FrequencyParametersPair(SCG.KeyValuePair<double, NetworkParametersMatrix> pair)
/// <summary>Creates a <see cref="FrequencyParametersPair"/> from a <see cref="KeyValuePair{TKey, TValue}"/> object.</summary>
public static implicit operator FrequencyParametersPair(KeyValuePair<double, NetworkParametersMatrix> pair)
=> new FrequencyParametersPair(pair.Key, pair.Value);
/// <summary>Creates a <see cref="SCG.KeyValuePair{TKey, TValue}"/> from a <see cref="FrequencyParametersPair"/> object.</summary>
public static implicit operator SCG.KeyValuePair<double, NetworkParametersMatrix>(FrequencyParametersPair pair)
=> new SCG.KeyValuePair<double, NetworkParametersMatrix>(pair.Frequency_Hz, pair.Parameters);
/// <summary>Creates a <see cref="KeyValuePair{TKey, TValue}"/> from a <see cref="FrequencyParametersPair"/> object.</summary>
public static implicit operator KeyValuePair<double, NetworkParametersMatrix>(FrequencyParametersPair pair)
=> new KeyValuePair<double, NetworkParametersMatrix>(pair.Frequency_Hz, pair.Parameters);

/// <summary>
/// Adds support for the ValueTuple deconstruction syntax for this object.
Expand Down Expand Up @@ -71,12 +69,12 @@ public FrequencyParametersPair(double frequency, TMatrix parameters)
Parameters = parameters;
}

/// <summary>Creates a <see cref="FrequencyParametersPair"/> from a <see cref="SCG.KeyValuePair{TKey, TValue}"/> object.</summary>
public static implicit operator FrequencyParametersPair<TMatrix>(SCG.KeyValuePair<double, TMatrix> pair)
/// <summary>Creates a <see cref="FrequencyParametersPair"/> from a <see cref="KeyValuePair{TKey, TValue}"/> object.</summary>
public static implicit operator FrequencyParametersPair<TMatrix>(KeyValuePair<double, TMatrix> pair)
=> new FrequencyParametersPair<TMatrix>(pair.Key, pair.Value);
/// <summary>Creates a <see cref="SCG.KeyValuePair{TKey, TValue}"/> from a <see cref="FrequencyParametersPair"/> object.</summary>
public static implicit operator SCG.KeyValuePair<double, TMatrix>(FrequencyParametersPair<TMatrix> pair)
=> new SCG.KeyValuePair<double, TMatrix>(pair.Frequency_Hz, pair.Parameters);
/// <summary>Creates a <see cref="KeyValuePair{TKey, TValue}"/> from a <see cref="FrequencyParametersPair"/> object.</summary>
public static implicit operator KeyValuePair<double, TMatrix>(FrequencyParametersPair<TMatrix> pair)
=> new KeyValuePair<double, TMatrix>(pair.Frequency_Hz, pair.Parameters);

/// <summary>
/// Adds support for the ValueTuple deconstruction syntax for this object.
Expand Down Expand Up @@ -107,23 +105,24 @@ public static explicit operator FrequencyParametersPair<TMatrix>(FrequencyParame
/// <typeparam name="TMatrix">Specifies the network parameter type contained within this collection.</typeparam>
public sealed class NetworkParametersCollection<TMatrix> : INetworkParametersCollection where TMatrix : NetworkParametersMatrix
{
private readonly Dictionary<double, TMatrix> networkParameters;
private readonly SortedArray<double> frequencies;
//private readonly Dictionary<double, TMatrix> networkParameters;
//private readonly SortedArray<double> frequencies;
private readonly SortedList<double, TMatrix> networkParameters;

/// <summary>Gets the number of ports of the device that this collection represents.</summary>
public int NumberOfPorts { get; }
/// <summary>Gets all frequencies defined in this collection in Hz.</summary>

#if NET45
public IReadOnlyCollection<double> Frequencies => networkParameters.Keys.ToList().AsReadOnly();
#if NET8_0_OR_GREATER
public IReadOnlyCollection<double> Frequencies => networkParameters.Keys.AsReadOnly();
#else
public IReadOnlyCollection<double> Frequencies => networkParameters.Keys;
public IReadOnlyCollection<double> Frequencies => new ReadOnlyCollection<double>(networkParameters.Keys);
#endif
/// <summary>Gets all the network parameters defined in this collection.</summary>
#if NET45
public IReadOnlyCollection<TMatrix> NetworkParameters => networkParameters.Values.ToList().AsReadOnly();
#if NET8_0_OR_GREATER
public IReadOnlyCollection<TMatrix> NetworkParameters => networkParameters.Values.AsReadOnly();
#else
public IReadOnlyCollection<TMatrix> NetworkParameters => networkParameters.Values;
public IReadOnlyCollection<TMatrix> NetworkParameters => new ReadOnlyCollection<TMatrix>(networkParameters.Values);
#endif
IReadOnlyCollection<NetworkParametersMatrix> INetworkParametersCollection.NetworkParameters => NetworkParameters;
/// <summary>Gets the specific subtype of <see cref="NetworkParametersMatrix"/> represented by this collection.</summary>
Expand All @@ -137,8 +136,7 @@ public sealed class NetworkParametersCollection<TMatrix> : INetworkParametersCol
public NetworkParametersCollection(int numPorts)
{
NumberOfPorts = numPorts;
networkParameters = new Dictionary<double, TMatrix>();
frequencies = new SortedArray<double>();
networkParameters = new SortedList<double, TMatrix>();
}
/// <summary>
/// Creates a new network parameters collection from a seqeunce of frequency and network parameter matrix pairs.
Expand All @@ -160,22 +158,15 @@ internal NetworkParametersCollection(IEnumerable<FrequencyParametersPair<TMatrix
}

/// <summary>
/// Creates a new <see cref="NetworkParametersCollection{TMatrix}"/> from an existing <see cref="SCG.IList{T}"/> of
/// Creates a new <see cref="NetworkParametersCollection{TMatrix}"/> from an existing <see cref="IList{T}"/> of
/// <see cref="FrequencyParametersPair{TMatrix}"/> pairs.
/// </summary>
/// <param name="parameters">The list of parameters </param>
/// <param name="sorted"></param>
public NetworkParametersCollection(SCG.IList<FrequencyParametersPair<TMatrix>> parameters, bool sorted = false)
public NetworkParametersCollection(IList<FrequencyParametersPair<TMatrix>> parameters, bool sorted = false)
{
networkParameters = new Dictionary<double, TMatrix>(parameters.Count);
frequencies = new SortedArray<double>(parameters.Count);

foreach (var (frequency, data) in parameters)
{
networkParameters[frequency] = data;
if (!sorted) frequencies.Add(frequency);
}
if (sorted) frequencies.AddSorted(parameters.Select(p => p.Frequency_Hz));
var dictionary = parameters.ToDictionary(el => el.Frequency_Hz, el => el.Parameters);
networkParameters = new SortedList<double, TMatrix>(dictionary);
}

/// <summary>
Expand Down Expand Up @@ -205,7 +196,6 @@ public TMatrix this[double frequency]
throw new ArgumentException("All network parameter matrices must have the same number of ports.");
}
networkParameters[frequency] = value;
frequencies.Add(frequency);
}
}

Expand All @@ -232,7 +222,6 @@ public TMatrix this[double frequency]
TMatrix matrix = (TMatrix)Activator.CreateInstance(typeof(TMatrix), NumberOfPorts);
matrix[destinationPort, sourcePort] = value;
networkParameters.Add(frequency, matrix);
frequencies.Add(frequency);
}
}
}
Expand All @@ -241,25 +230,36 @@ public TMatrix this[double frequency]
/// <returns>The <see cref="NetworkParametersMatrix"/> at or nearest to <paramref name="frequency"/>.</returns>
public TMatrix Nearest(double frequency)
{
bool predecessorFound = frequencies.TryWeakPredecessor(frequency, out double predecessor);
bool successorFound = frequencies.TryWeakSuccessor(frequency, out double successor);

if (predecessorFound && successorFound)
bool found = networkParameters.TryGetValue(frequency, out TMatrix value);
if (!found)
{
double preDelta = Math.Abs(predecessor - frequency);
double postDelta = Math.Abs(successor - frequency);
// Keys is cached by the sorted list implementation and not regenerated each time
int location = networkParameters.Keys.BinarySearch(frequency);

return preDelta < postDelta ? this[predecessor] : this[successor];
}
else if (predecessorFound)
{
return this[predecessor];
}
else if (successorFound)
{
return this[successor];
location = ~location;

if (location == 0)
{
return networkParameters.Values.First();
}
else if (location >= networkParameters.Count)
{
return networkParameters.Values.Last();
}
else
{
int predecssorLocation = location - 1;

double predecessor = networkParameters.Keys[predecssorLocation];
double successor = networkParameters.Keys[location];

double preDelta = Math.Abs(predecessor - frequency);
double postDelta = Math.Abs(successor - frequency);

return preDelta < postDelta ? this[predecessor] : this[successor];
}
}
throw new ArgumentOutOfRangeException(nameof(frequency));
else return value;
}
NetworkParametersMatrix INetworkParametersCollection.Nearest(double frequency) => Nearest(frequency);
/// <summary>Gets the number of <see cref="FrequencyParametersPair"/> objects contained in the collection.</summary>
Expand All @@ -283,7 +283,6 @@ public TMatrix Nearest(double frequency)
public void Clear()
{
networkParameters.Clear();
frequencies.Clear();
}
/// <summary>
/// Attempts to remove the <see cref="NetworkParametersMatrix"/> at the specified frequency from the collection.
Expand All @@ -292,9 +291,7 @@ public void Clear()
/// <returns>True if the element is successfully found and removed; false if not.</returns>
public bool Remove(double frequency)
{
bool one = networkParameters.Remove(frequency);
bool two = frequencies.Remove(frequency);
return one & two;
return networkParameters.Remove(frequency);
}
/// <summary>
/// Gets the <see cref="NetworkParametersMatrix"/> associated with the specified frequency.
Expand Down Expand Up @@ -346,7 +343,7 @@ public static NetworkParametersCollection<T> Cascade<T>(params INetworkParameter
}

#region Explicit ICollection Implementations
bool SCG.ICollection<FrequencyParametersPair>.IsReadOnly => false;
bool ICollection<FrequencyParametersPair>.IsReadOnly => false;


NetworkParametersMatrix INetworkParametersCollection.this[double frequency]
Expand All @@ -356,7 +353,7 @@ NetworkParametersMatrix INetworkParametersCollection.this[double frequency]
}


bool SCG.ICollection<FrequencyParametersPair>.Contains(FrequencyParametersPair item)
bool ICollection<FrequencyParametersPair>.Contains(FrequencyParametersPair item)
{
if (networkParameters.TryGetValue(item.Frequency_Hz, out TMatrix value))
{
Expand All @@ -365,13 +362,13 @@ bool SCG.ICollection<FrequencyParametersPair>.Contains(FrequencyParametersPair i
else return false;
}

void SCG.ICollection<FrequencyParametersPair>.CopyTo(FrequencyParametersPair[] array, int arrayIndex)
void ICollection<FrequencyParametersPair>.CopyTo(FrequencyParametersPair[] array, int arrayIndex)
{
var arr = Array.ConvertAll(array, f => (SCG.KeyValuePair<double, NetworkParametersMatrix>)f);
((SCG.ICollection<SCG.KeyValuePair<double, NetworkParametersMatrix>>)networkParameters).CopyTo(arr, arrayIndex);
var arr = Array.ConvertAll(array, f => (KeyValuePair<double, NetworkParametersMatrix>)f);
((ICollection<KeyValuePair<double, NetworkParametersMatrix>>)networkParameters).CopyTo(arr, arrayIndex);
}

bool SCG.ICollection<FrequencyParametersPair>.Remove(FrequencyParametersPair item)
bool ICollection<FrequencyParametersPair>.Remove(FrequencyParametersPair item)
{
return Remove(item.Frequency_Hz);
}
Expand All @@ -391,7 +388,7 @@ bool INetworkParametersCollection.TryGetValue(double frequency, out NetworkParam
return found;
}

void SCG.ICollection<FrequencyParametersPair>.Add(FrequencyParametersPair item) => Add(item.Frequency_Hz, item.Parameters.ConvertParameterType<TMatrix>());
void ICollection<FrequencyParametersPair>.Add(FrequencyParametersPair item) => Add(item.Frequency_Hz, item.Parameters.ConvertParameterType<TMatrix>());

IEnumerator<FrequencyParametersPair> IEnumerable<FrequencyParametersPair>.GetEnumerator()
{
Expand Down
Loading

0 comments on commit 3e35430

Please sign in to comment.