Skip to content

Commit

Permalink
Merge pull request #11 from HamletTanyavong/dev
Browse files Browse the repository at this point in the history
Add vectors, matrices, and QR decomposition
  • Loading branch information
HamletTanyavong authored Oct 17, 2023
2 parents 47fc4ea + 425b67b commit 8c9ae8e
Show file tree
Hide file tree
Showing 20 changed files with 1,897 additions and 18 deletions.
4 changes: 4 additions & 0 deletions src/Mathematics.NET/Core/ComplexNumber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,13 @@ public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatPro

public static ComplexNumber Conjugate(ComplexNumber z) => new(z._real, -z._imaginary);

public static ComplexNumber FromDouble(double x) => new(x);

public static ComplexNumber FromPolarForm(Real magnitude, Real phase)
=> new(magnitude * Math.Cos(phase.Value), magnitude * Math.Sin(phase.Value));

public static ComplexNumber FromReal(Real x) => new(x);

private static double Hypot(double x, double y)
{
// Factor out the larger value to avoid possible overflow
Expand Down
18 changes: 17 additions & 1 deletion src/Mathematics.NET/Core/IComplex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@ static virtual T CreateTruncating<U>(U value)
return result;
}

/// <summary>Create an instance of type <typeparamref name="T"/> from one of type <see cref="double"/></summary>
/// <param name="x">A value of type <see cref="double"/></param>
/// <returns>An instance of type <typeparamref name="T"/> created from <paramref name="x"/></returns>
static abstract T FromDouble(double x);

/// <summary>Create an instance of type <typeparamref name="T"/> from one of type <see cref="Real"/></summary>
/// <remarks>If the value to convert from is also of type <see cref="Real"/>, return itself</remarks>
/// <param name="x">A value of type <see cref="Real"/></param>
/// <returns>An instance of type <typeparamref name="T"/> created from <paramref name="x"/></returns>
static abstract T FromReal(Real x);

/// <summary>Check if a value is finite</summary>
/// <param name="z">The value to check</param>
/// <returns><see langword="true"/> if the value is finite; otherwise, <see langword="false"/></returns>
Expand Down Expand Up @@ -261,5 +272,10 @@ protected static abstract bool TryConvertToTruncating<U>(T value, [MaybeNullWhen

/// <summary>Convert a value of type <see cref="IFloatingPointIeee754{TSelf}"/> to one of type <typeparamref name="T"/></summary>
/// <param name="x">The value to convert</param>
static virtual implicit operator T(double x) => T.CreateSaturating(x);
static virtual implicit operator T(double x) => T.FromDouble(x);

/// <summary>Convert a value of type <see cref="Real"/> to one of type <typeparamref name="T"/></summary>
/// <remarks>If the type to convert from is also <see cref="Real"/>, return itself</remarks>
/// <param name="x">The value to convert</param>
static virtual implicit operator T(Real x) => T.FromReal(x);
}
11 changes: 11 additions & 0 deletions src/Mathematics.NET/Core/IReal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,15 @@ public interface IReal<T>
/// <param name="y">The second value</param>
/// <returns>The lesser of the two values</returns>
static abstract T Min(T x, T y);

/// <summary>Find the sign of a real number</summary>
/// <param name="x">The value to check</param>
/// <returns>
/// A number indicating the sign of the value:<br/><br/>
/// <b>1</b> if the value is greater than zero<br/>
/// <b>0</b> if the value is greater than zero<br/>
/// <b>-1</b> if the value is less than zero
/// </returns>
/// <exception cref="ArithmeticException">An overflow or underflow has occurred</exception>
static abstract int Sign(T x);
}
19 changes: 17 additions & 2 deletions src/Mathematics.NET/Core/Rational.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatPro

public static Rational<T> Conjugate(Rational<T> x) => x;

public static Rational<T> FromDouble(double x) => (Rational<T>)x;

public static Rational<T> FromReal(Real x) => (Rational<T>)x;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static T GCD(T p, T q)
{
Expand Down Expand Up @@ -526,6 +530,15 @@ public static Rational<T> Reduce(Rational<T> x)
return new(x._numerator / gcd, x._denominator / gcd);
}

public static int Sign(Rational<T> x)
{
if (x == Rational<T>.Zero)
{
return 0;
}
return x._numerator > T.Zero ? 1 : -1;
}

public static bool TryConvertFromChecked<U>(U value, out Rational<T> result)
where U : INumberBase<U>
{
Expand Down Expand Up @@ -603,9 +616,9 @@ public static bool TryConvertToTruncating<U>(Rational<T> value, [MaybeNullWhen(f
//

// TODO: Find a better implementation
public static explicit operator Rational<T>(Real x)
public static explicit operator Rational<T>(double x)
{
var value = x.Value;
var value = x;
if (double.IsNaN(value) || double.IsInfinity(value))
{
return NaN;
Expand All @@ -625,6 +638,8 @@ public static explicit operator Rational<T>(Real x)
return new(num / gcd, den / gcd);
}

public static explicit operator Rational<T>(Real x) => (Rational<T>)x.Value;

public static explicit operator checked Real(Rational<T> x) => checked(double.CreateChecked(x._numerator) / double.CreateChecked(x._denominator));

public static explicit operator Real(Rational<T> x) => double.CreateSaturating(x._numerator) / double.CreateSaturating(x._denominator);
Expand Down
6 changes: 6 additions & 0 deletions src/Mathematics.NET/Core/Real.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatPro

public static Real Conjugate(Real x) => x;

public static Real FromDouble(double x) => new(x);

public static Real FromReal(Real x) => x;

public static Real Hypot(Real x, Real y) => double.Hypot(x._value, y._value);

public static bool IsFinite(Real x) => double.IsFinite(x._value);
Expand Down Expand Up @@ -289,6 +293,8 @@ public static Real Reciprocate(Real x)
return 1.0 / x;
}

public static int Sign(Real x) => Math.Sign(x._value);

public static bool TryConvertFromChecked<U>(U value, out Real result)
where U : INumberBase<U>
{
Expand Down
62 changes: 62 additions & 0 deletions src/Mathematics.NET/ExternalExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// <copyright file="ExternalExtensions.cs" company="Mathematics.NET">
// Mathematics.NET
// https://github.com/HamletTanyavong/Mathematics.NET
//
// MIT License
//
// Copyright (c) 2023 Hamlet Tanyavong
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// </copyright>

using System.Text;

namespace Mathematics.NET;

/// <summary>A class containing extension methods for external .NET objects</summary>
public static class ExternalExtensions
{
/// <summary>Remove specified characters from the end of a string being built by a string builder</summary>
/// <param name="builder">A string builder instance</param>
/// <param name="unwantedChars">An array of characters to trim</param>
/// <returns>The same string builder with characters removed</returns>
public static StringBuilder TrimEnd(this StringBuilder builder, params char[]? unwantedChars)
{
if (unwantedChars == null || builder.Length == 0 || unwantedChars.Length == 0)
{
return builder;
}

int i = builder.Length - 1;
while (i >= 0)
{
if (!unwantedChars.Contains(builder[i]))
{
break;
}
i--;
}
if (i < builder.Length - 1)
{
builder.Length = ++i;
}

return builder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
// SOFTWARE.
// </copyright>

using Mathematics.NET.Core;

namespace Mathematics.NET.LinearAlgebra.Abstractions;

/// <summary>Defines support for mathematical objects that can be represented by arrays</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
// SOFTWARE.
// </copyright>

using Mathematics.NET.Core;
using Mathematics.NET.Core.Operations;
using Mathematics.NET.Core.Relations;

Expand Down Expand Up @@ -57,8 +56,7 @@ public interface IOneDimensionalArrayRepresentable<T, U>
/// <returns>The norm</returns>
Real Norm();

/// <summary>Normalize a given vector</summary>
/// <param name="vector">The vector to normalize</param>
/// <summary>Normalize the vector</summary>
/// <returns>The normalized vector</returns>
T Normalize();
}
57 changes: 57 additions & 0 deletions src/Mathematics.NET/LinearAlgebra/Abstractions/ISquareMatrix.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// <copyright file="ISquareMatrix.cs" company="Mathematics.NET">
// Mathematics.NET
// https://github.com/HamletTanyavong/Mathematics.NET
//
// MIT License
//
// Copyright (c) 2023 Hamlet Tanyavong
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// </copyright>

namespace Mathematics.NET.LinearAlgebra.Abstractions;

/// <summary>Defines support for square matrices</summary>
/// <typeparam name="T">A type that implements <see cref="ITwoDimensionalArrayRepresentable{T, U}"/></typeparam>
/// <typeparam name="U">A type that implements <see cref="IComplex{T}"/></typeparam>
public interface ISquareMatrix<T, U>
where T : ITwoDimensionalArrayRepresentable<T, U>
where U : IComplex<U>
{
/// <summary>Represents a value that is not a matrix</summary>
/// <remarks>This result will be returned when trying to invert a singular matrix</remarks>
static abstract T NaM { get; }

/// <summary>Compute the determinant of the matrix</summary>
/// <returns>The determinant</returns>
U Determinant();

/// <summary>Compute the inverse of the matrix</summary>
/// <returns>The inverse if the matrix is invertible; otherwise, <see cref="NaM"/></returns>
T Inverse();

/// <summary>Check if a value is not a matrix</summary>
/// <param name="matrix">The value to check</param>
/// <returns><see langword="true"/> if the value is not a matrix; otherwise, <see langword="false"/></returns>
static abstract bool IsNaM(T matrix);

/// <summary>Compute the trace of the matrix</summary>
/// <returns>The trace</returns>
U Trace();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// <copyright file="ITwoDimensionalArrayRepresentable.cs" company="Mathematics.NET">
// Mathematics.NET
// https://github.com/HamletTanyavong/Mathematics.NET
//
// MIT License
//
// Copyright (c) 2023 Hamlet Tanyavong
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// </copyright>

using Mathematics.NET.Core.Operations;
using Mathematics.NET.Core.Relations;

namespace Mathematics.NET.LinearAlgebra.Abstractions;

/// <summary>Defines support for mathematical objects that can be represented by two-dimensional arrays</summary>
/// <typeparam name="T">The type that implements the interface</typeparam>
/// <typeparam name="U">A type that implements <see cref="IComplex{T}"/></typeparam>
public interface ITwoDimensionalArrayRepresentable<T, U>
: IArrayRepresentable<U>,
IAdditionOperation<T, T>,
ISubtractionOperation<T, T>,
IMultiplicationOperation<T, T>,
IEqualityRelation<T, bool>,
IFormattable
where T : ITwoDimensionalArrayRepresentable<T, U>
where U : IComplex<U>
{
/// <summary>The number of rows in the array</summary>
static abstract int E1Components { get; }

/// <summary>The number of columns in the array</summary>
static abstract int E2Components { get; }

/// <summary>Get the element at the specified row and column</summary>
/// <param name="row">The row</param>
/// <param name="column">The column</param>
/// <returns>The element at the specified row and column</returns>
U this[int row, int column] { get; set; }
}
Loading

0 comments on commit 8c9ae8e

Please sign in to comment.