Skip to content

Commit

Permalink
clean up: nullable refs + xml + exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
ZacharyPatten committed Jun 27, 2021
1 parent 911a9ad commit 6deecb2
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 139 deletions.
2 changes: 1 addition & 1 deletion Sources/Towel/DataStructures/Bag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public class BagMap<T, TMap> : IBag<T>,
#region Constructors

/// <summary>Constructs a bag map.</summary>
internal BagMap(TMap map = default)
internal BagMap(TMap map)
{
_map = map;
_count = 0;
Expand Down
50 changes: 26 additions & 24 deletions Sources/Towel/DataStructures/Trie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static class Trie
{
throw exception ?? new ArgumentException($"{nameof(Get)} failed but the {nameof(exception)} is null");
}
return value;
return value!;
}

/// <summary>Removes a value.</summary>
Expand Down Expand Up @@ -111,9 +111,11 @@ public class TrieLinkedHashLinked<T, TEquate, THash> : ITrie<T>,

internal class Node
{
internal MapHashLinked<Node, T, TEquate, THash>? Map;
internal MapHashLinked<Node, T, TEquate, THash> Map;
internal bool IsLeaf;
internal int Count;

public Node(MapHashLinked<Node, T, TEquate, THash> map) => Map = map;
}

#endregion
Expand Down Expand Up @@ -170,7 +172,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, TEquate, THash> trie)
}
else
{
Node temp = new() { Map = new(Equate, Hash) };
Node temp = new(map: new(Equate, Hash));
map[key] = temp;
node = temp;
}
Expand Down Expand Up @@ -200,8 +202,8 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, TEquate, THash> trie)
{
return (false, new ArgumentNullException(nameof(stepper)));
}
var pathStack = new StackLinked<(T, MapHashLinked<Node, T, TEquate, THash>, Node)>();
T finalKey = default;
StackLinked<(T, MapHashLinked<Node, T, TEquate, THash>, Node)> stack = new();
T finalKey;
MapHashLinked<Node, T, TEquate, THash>? finalMap = null;
Node? node = null;
Exception? exception = null;
Expand All @@ -217,7 +219,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, TEquate, THash> trie)
{
exception ??= new ArgumentException("Attempted to remove a non-existing item.", nameof(stepper));
}
pathStack.Push((finalKey, finalMap, node));
stack.Push((finalKey, finalMap, node!));
});
if (exception is not null)
{
Expand All @@ -234,9 +236,9 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, TEquate, THash> trie)
else
{
bool remove = true;
while (pathStack.Count > 0)
while (stack.Count > 0)
{
var (k, m, n) = pathStack.Pop();
var (k, m, n) = stack.Pop();
n.Count--;
if (remove && n.Count is 0)
{
Expand Down Expand Up @@ -266,9 +268,7 @@ public bool Contains(Action<Action<T>> stepper)
}
else
{
var map = node is null
? _map
: node.Map;
var map = node is null ? _map : node.Map;
if (map.Contains(key))
{
node = map[key];
Expand Down Expand Up @@ -360,7 +360,7 @@ public interface ITrie<T, D> : IDataStructure<(Action<Action<T>>, D)>,
/// <summary>Tries to get a value.</summary>
/// <param name="stepper">The relative keys of the value.</param>
/// <returns>True if the remove was successful or false if not.</returns>
(bool Success, D Value, Exception? Exception) TryGet(Action<Action<T>> stepper);
(bool Success, D? Value, Exception? Exception) TryGet(Action<Action<T>> stepper);

/// <summary>Tries to remove a value.</summary>
/// <param name="stepper">The relative keys of the value.</param>
Expand Down Expand Up @@ -391,10 +391,12 @@ public class TrieLinkedHashLinked<T, D, TEquate, THash> : ITrie<T, D>,

internal class Node
{
internal MapHashLinked<Node, T, TEquate, THash>? Map;
internal D Value;
internal MapHashLinked<Node, T, TEquate, THash> Map;
internal D? Value;
internal bool HasValue;
internal int Count;

public Node(MapHashLinked<Node, T, TEquate, THash> map) => Map = map;
}

#endregion
Expand Down Expand Up @@ -440,7 +442,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
{
return (false, new ArgumentNullException(nameof(stepper)));
}
IStack<Node> stack = new StackLinked<Node>();
StackLinked<Node> stack = new();
Node? node = null;
stepper(key =>
{
Expand All @@ -451,7 +453,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
}
else
{
Node temp = new() { Map = new(Equate, Hash) };
Node temp = new(map: new(Equate, Hash));
map[key] = temp;
node = temp;
}
Expand All @@ -476,7 +478,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
}

/// <inheritdoc/>
public (bool Success, D Value, Exception? Exception) TryGet(Action<Action<T>> stepper)
public (bool Success, D? Value, Exception? Exception) TryGet(Action<Action<T>> stepper)
{
if (stepper is null)
{
Expand All @@ -492,7 +494,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
}
else
{
Node temp = new() { Map = new(Equate, Hash) };
Node temp = new(map: new(Equate, Hash));
map[key] = temp;
node = temp;
}
Expand All @@ -518,9 +520,9 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
{
return (false, new ArgumentNullException(nameof(stepper)));
}
var pathStack = new StackLinked<(T, MapHashLinked<Node, T, TEquate, THash>, Node)>();
StackLinked<(T, MapHashLinked<Node, T, TEquate, THash>, Node)> stack = new();
T finalKey;
MapHashLinked<Node, T, TEquate, THash>? finalMap;
MapHashLinked<Node, T, TEquate, THash> finalMap;
Node? node = null;
Exception? capturedException = null;
stepper(key =>
Expand All @@ -535,7 +537,7 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
{
capturedException ??= new ArgumentException("Attempted to remove a non-existing item.", nameof(stepper));
}
pathStack.Push((finalKey, finalMap, node));
stack.Push((finalKey, finalMap, node!));
});
if (capturedException is not null)
{
Expand All @@ -552,9 +554,9 @@ public TrieLinkedHashLinked(TrieLinkedHashLinked<T, D, TEquate, THash> trie)
else
{
bool remove = true;
while (pathStack.Count > 0)
while (stack.Count > 0)
{
var (k, m, n) = pathStack.Pop();
var (k, m, n) = stack.Pop();
n.Count--;
if (remove && n.Count is 0)
{
Expand Down Expand Up @@ -617,7 +619,7 @@ StepStatus Stepper(Node node, Action<Action<T>> stepper)
{
if (node.HasValue)
{
if (step.Invoke((stepper, node.Value)) is Break)
if (step.Invoke((stepper, node.Value!)) is Break)
{
return Break;
}
Expand Down
41 changes: 22 additions & 19 deletions Sources/Towel/Mathematics/Matrix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,11 @@ internal static void GetCofactor(Matrix<T> a, Matrix<T> temp, int p, int q, int
/// <summary>
/// Used to avoid issues when 1/2 + 1/2 = 0 + 0 = 0 instead of 1 for types, where division results in precision loss
/// </summary>
/// <typeparam name="T"></typeparam>
private sealed class MatrixElementFraction<T>
#pragma warning disable CS0660 // Type defines operator == or operator != but does not override Object.Equals(object o)
#pragma warning disable CS0661 // Type defines operator == or operator != but does not override Object.GetHashCode()
private sealed class MatrixElementFraction
#pragma warning restore CS0661 // Type defines operator == or operator != but does not override Object.GetHashCode()
#pragma warning restore CS0660 // Type defines operator == or operator != but does not override Object.Equals(object o)
{
private readonly T Numerator;
private readonly T Denominator;
Expand All @@ -408,26 +411,26 @@ internal MatrixElementFraction(T num, T den)
public T Value => Division(Numerator, Denominator);

// a / b + c / d = (a * d + b * c) / (b * d)
public static MatrixElementFraction<T> operator +(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static MatrixElementFraction operator +(MatrixElementFraction a, MatrixElementFraction b)
=> new(Addition(
Multiplication(a.Numerator, b.Denominator),
Multiplication(a.Denominator, b.Numerator)
), Multiplication(a.Denominator, b.Denominator));

public static MatrixElementFraction<T> operator *(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static MatrixElementFraction operator *(MatrixElementFraction a, MatrixElementFraction b)
=> new(Multiplication(a.Numerator, b.Numerator), Multiplication(a.Denominator, b.Denominator));

public static MatrixElementFraction<T> operator -(MatrixElementFraction<T> a)
public static MatrixElementFraction operator -(MatrixElementFraction a)
=> new(Multiplication(a.Numerator, Constant<T>.NegativeOne), a.Denominator);

public static MatrixElementFraction<T> operator -(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static MatrixElementFraction operator -(MatrixElementFraction a, MatrixElementFraction b)
=> a + (-b);

// a / b / (d / c) = (a * c) / (b * d)
public static MatrixElementFraction<T> operator /(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static MatrixElementFraction operator /(MatrixElementFraction a, MatrixElementFraction b)
=> new(Multiplication(a.Numerator, b.Denominator), Multiplication(a.Denominator, b.Numerator));

public static bool operator <(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static bool operator <(MatrixElementFraction a, MatrixElementFraction b)
{
var c = Multiplication(a.Numerator, b.Denominator);
var d = Multiplication(b.Numerator, a.Denominator);
Expand All @@ -437,25 +440,25 @@ internal MatrixElementFraction(T num, T den)
return !LessThan(c, d);
}

public static bool operator ==(MatrixElementFraction<T> a, MatrixElementFraction<T> b) =>
public static bool operator ==(MatrixElementFraction a, MatrixElementFraction b) =>
Equate(a.Numerator, b.Numerator) &&
Equate(a.Denominator, b.Denominator);
public static bool operator !=(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static bool operator !=(MatrixElementFraction a, MatrixElementFraction b)
=> !(a == b);

public static bool operator >(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static bool operator >(MatrixElementFraction a, MatrixElementFraction b)
=> a >= b && !(a == b);

public static bool operator >=(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static bool operator >=(MatrixElementFraction a, MatrixElementFraction b)
=> !(a < b);

public static bool operator <=(MatrixElementFraction<T> a, MatrixElementFraction<T> b)
public static bool operator <=(MatrixElementFraction a, MatrixElementFraction b)
=> a < b || a == b;

public static explicit operator MatrixElementFraction<T>(int val)
public static explicit operator MatrixElementFraction(int val)
=> new(Convert<int, T>(val));

public MatrixElementFraction<T> Abs()
public MatrixElementFraction Abs()
=> new(AbsoluteValue(Numerator), AbsoluteValue(Denominator));

public bool IsDividedByZero => Equate(Denominator, Constant<T>.Zero);
Expand All @@ -474,8 +477,8 @@ internal static T GetDeterminantGaussian(Matrix<T> matrix, int n)
{
return matrix.Get(0, 0);
}
MatrixElementFraction<T> determinant = new(Constant<T>.One);
Matrix<MatrixElementFraction<T>> fractioned = new(matrix.Rows, matrix.Columns, (r, c) => new MatrixElementFraction<T>(matrix.Get(r, c)));
MatrixElementFraction determinant = new(Constant<T>.One);
Matrix<MatrixElementFraction> fractioned = new(matrix.Rows, matrix.Columns, (r, c) => new(matrix.Get(r, c)));
for (int i = 0; i < n; i++)
{
var pivotElement = fractioned.Get(i, i);
Expand All @@ -494,7 +497,7 @@ internal static T GetDeterminantGaussian(Matrix<T> matrix, int n)
}
if (pivotRow != i)
{
Matrix<MatrixElementFraction<T>>.SwapRows(fractioned, i, pivotRow, 0, n - 1);
Matrix<MatrixElementFraction>.SwapRows(fractioned, i, pivotRow, 0, n - 1);
determinant = Negation(determinant);
}
determinant *= pivotElement;
Expand All @@ -505,7 +508,7 @@ internal static T GetDeterminantGaussian(Matrix<T> matrix, int n)
// reference: matrix[row][column] -= matrix[row][i] * matrix[i][column] / pivotElement;
fractioned.Set(row, column,
// D - A * B / C
D_subtract_A_multiply_B_divide_C<MatrixElementFraction<T>>.Function(
D_subtract_A_multiply_B_divide_C<MatrixElementFraction>.Function(
/* A */ fractioned.Get(row, i),
/* B */ fractioned.Get(i, column),
/* C */ pivotElement,
Expand Down

0 comments on commit 6deecb2

Please sign in to comment.