Skip to content

Commit

Permalink
Merge pull request #149 from HamletTanyavong/dev
Browse files Browse the repository at this point in the history
Update tensor implementations
  • Loading branch information
HamletTanyavong authored Oct 2, 2024
2 parents baaeed5 + 546902a commit 971ed40
Show file tree
Hide file tree
Showing 25 changed files with 517 additions and 365 deletions.
31 changes: 31 additions & 0 deletions src/Mathematics.NET/AutoDiff/Dual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Mathematics.NET.DifferentialGeometry;
using Mathematics.NET.DifferentialGeometry.Abstractions;
using Mathematics.NET.LinearAlgebra;

namespace Mathematics.NET.AutoDiff;

Expand Down Expand Up @@ -248,4 +251,32 @@ public static Dual<T> Tan(Dual<T> x)
/// <returns>A dual number.</returns>
public static Dual<T> CustomOperation(Dual<T> x, Dual<T> y, Func<T, T, T> f, Func<T, T, T> dfx, Func<T, T, T> dfy)
=> new(f(x._d0, y._d0), dfy(x._d0, y._d0) * x._d1 + dfx(x._d0, y._d1) * y._d1);

//
// DifGeo
//

public static AutoDiffTensor2<Dual<T>, T, U> CreateAutoDiffTensor<U>(in Vector2<T> x, in Vector2<T> seed)
where U : IIndex
=> new(CreateVariable(x.X1, seed.X1), CreateVariable(x.X2, seed.X2));

public static AutoDiffTensor2<Dual<T>, T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T seed0, in T seed1)
where U : IIndex
=> new(CreateVariable(x0, seed0), CreateVariable(x1, seed1));

public static AutoDiffTensor3<Dual<T>, T, U> CreateAutoDiffTensor<U>(in Vector3<T> x, in Vector3<T> seed)
where U : IIndex
=> new(CreateVariable(x.X1, seed.X1), CreateVariable(x.X2, seed.X2), CreateVariable(x.X3, seed.X3));

public static AutoDiffTensor3<Dual<T>, T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2, in T seed0, in T seed1, in T seed2)
where U : IIndex
=> new(CreateVariable(x0, seed0), CreateVariable(x1, seed1), CreateVariable(x2, seed2));

public static AutoDiffTensor4<Dual<T>, T, U> CreateAutoDiffTensor<U>(in Vector4<T> x, in Vector4<T> seed)
where U : IIndex
=> new(CreateVariable(x.X1, seed.X1), CreateVariable(x.X2, seed.X2), CreateVariable(x.X3, seed.X3), CreateVariable(x.X4, seed.X4));

public static AutoDiffTensor4<Dual<T>, T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2, in T x3, in T seed0, in T seed1, in T seed2, in T seed3)
where U : IIndex
=> new(CreateVariable(x0, seed0), CreateVariable(x1, seed1), CreateVariable(x2, seed2), CreateVariable(x3, seed3));
}
35 changes: 33 additions & 2 deletions src/Mathematics.NET/AutoDiff/GradientTape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Mathematics.NET.DifferentialGeometry;
using Mathematics.NET.DifferentialGeometry.Abstractions;
using Mathematics.NET.LinearAlgebra;
using Microsoft.Extensions.Logging;

namespace Mathematics.NET.AutoDiff;
Expand Down Expand Up @@ -102,10 +105,10 @@ public GradientTape(int n, bool isTracking = true)
// Methods
//

public Variable<T> CreateVariable(T seed)
public Variable<T> CreateVariable(T value)
{
_nodes.Add(new(_variableCount));
Variable<T> variable = new(_variableCount++, seed);
Variable<T> variable = new(_variableCount++, value);
return variable;
}

Expand Down Expand Up @@ -665,4 +668,32 @@ public Variable<T> CustomOperation(Variable<T> x, Variable<T> y, Func<T, T, T> f
}
return new(_nodes.Count, f(x.Value, y.Value));
}

//
// DifGeo
//

public AutoDiffTensor2<T, U> CreateAutoDiffTensor<U>(in Vector2<T> x)
where U : IIndex
=> new(CreateVariable(x.X1), CreateVariable(x.X2));

public AutoDiffTensor2<T, U> CreateAutoDiffTensor<U>(in T x0, in T x1)
where U : IIndex
=> new(CreateVariable(x0), CreateVariable(x1));

public AutoDiffTensor3<T, U> CreateAutoDiffTensor<U>(in Vector3<T> x)
where U : IIndex
=> new(CreateVariable(x.X1), CreateVariable(x.X2), CreateVariable(x.X3));

public AutoDiffTensor3<T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2)
where U : IIndex
=> new(CreateVariable(x0), CreateVariable(x1), CreateVariable(x2));

public AutoDiffTensor4<T, U> CreateAutoDiffTensor<U>(in Vector4<T> x)
where U : IIndex
=> new(CreateVariable(x.X1), CreateVariable(x.X2), CreateVariable(x.X3), CreateVariable(x.X4));

public AutoDiffTensor4<T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2, in T x3)
where U : IIndex
=> new(CreateVariable(x0), CreateVariable(x1), CreateVariable(x2), CreateVariable(x3));
}
35 changes: 33 additions & 2 deletions src/Mathematics.NET/AutoDiff/HessianTape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Mathematics.NET.DifferentialGeometry;
using Mathematics.NET.DifferentialGeometry.Abstractions;
using Mathematics.NET.LinearAlgebra;
using Microsoft.Extensions.Logging;

namespace Mathematics.NET.AutoDiff;
Expand Down Expand Up @@ -69,10 +72,10 @@ public HessianTape(int n, bool isTracking = true)
// Methods
//

public Variable<T> CreateVariable(T seed)
public Variable<T> CreateVariable(T value)
{
_nodes.Add(new(_variableCount));
Variable<T> variable = new(_variableCount++, seed);
Variable<T> variable = new(_variableCount++, value);
return variable;
}

Expand Down Expand Up @@ -846,4 +849,32 @@ public Variable<T> CustomOperation(
}
return new(_nodes.Count, f(x.Value, y.Value));
}

//
// DifGeo
//

public AutoDiffTensor2<T, U> CreateAutoDiffTensor<U>(in Vector2<T> x)
where U : IIndex
=> new(CreateVariable(x.X1), CreateVariable(x.X2));

public AutoDiffTensor2<T, U> CreateAutoDiffTensor<U>(in T x0, in T x1)
where U : IIndex
=> new(CreateVariable(x0), CreateVariable(x1));

public AutoDiffTensor3<T, U> CreateAutoDiffTensor<U>(in Vector3<T> x)
where U : IIndex
=> new(CreateVariable(x.X1), CreateVariable(x.X2), CreateVariable(x.X3));

public AutoDiffTensor3<T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2)
where U : IIndex
=> new(CreateVariable(x0), CreateVariable(x1), CreateVariable(x2));

public AutoDiffTensor4<T, U> CreateAutoDiffTensor<U>(in Vector4<T> x)
where U : IIndex
=> new(CreateVariable(x.X1), CreateVariable(x.X2), CreateVariable(x.X3), CreateVariable(x.X4));

public AutoDiffTensor4<T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2, in T x3)
where U : IIndex
=> new(CreateVariable(x0), CreateVariable(x1), CreateVariable(x2), CreateVariable(x3));
}
31 changes: 31 additions & 0 deletions src/Mathematics.NET/AutoDiff/HyperDual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Mathematics.NET.DifferentialGeometry;
using Mathematics.NET.DifferentialGeometry.Abstractions;
using Mathematics.NET.LinearAlgebra;

namespace Mathematics.NET.AutoDiff;

Expand Down Expand Up @@ -275,4 +278,32 @@ public static HyperDual<T> CustomOperation(
Func<Dual<T>, Dual<T>, Dual<T>> dfx,
Func<Dual<T>, Dual<T>, Dual<T>> dfy)
=> new(f(x._d0, y._d0), dfy(x._d0, y._d0) * x._d1 + dfx(x._d0, y._d1) * y._d1);

//
// DifGeo
//

public static AutoDiffTensor2<HyperDual<T>, T, U> CreateAutoDiffTensor<U>(in Vector2<T> x, in Vector2<T> seed)
where U : IIndex
=> new(CreateVariable(x.X1, seed.X1), CreateVariable(x.X2, seed.X2));

public static AutoDiffTensor2<HyperDual<T>, T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T seed0, in T seed1)
where U : IIndex
=> new(CreateVariable(x0, seed0), CreateVariable(x1, seed1));

public static AutoDiffTensor3<HyperDual<T>, T, U> CreateAutoDiffTensor<U>(in Vector3<T> x, in Vector3<T> seed)
where U : IIndex
=> new(CreateVariable(x.X1, seed.X1), CreateVariable(x.X2, seed.X2), CreateVariable(x.X3, seed.X3));

public static AutoDiffTensor3<HyperDual<T>, T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2, in T seed0, in T seed1, in T seed2)
where U : IIndex
=> new(CreateVariable(x0, seed0), CreateVariable(x1, seed1), CreateVariable(x2, seed2));

public static AutoDiffTensor4<HyperDual<T>, T, U> CreateAutoDiffTensor<U>(in Vector4<T> x, in Vector4<T> seed)
where U : IIndex
=> new(CreateVariable(x.X1, seed.X1), CreateVariable(x.X2, seed.X2), CreateVariable(x.X3, seed.X3), CreateVariable(x.X4, seed.X4));

public static AutoDiffTensor4<HyperDual<T>, T, U> CreateAutoDiffTensor<U>(in T x0, in T x1, in T x2, in T x3, in T seed0, in T seed1, in T seed2, in T seed3)
where U : IIndex
=> new(CreateVariable(x0, seed0), CreateVariable(x1, seed1), CreateVariable(x2, seed2), CreateVariable(x3, seed3));
}
109 changes: 88 additions & 21 deletions src/Mathematics.NET/AutoDiff/IDual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,51 +27,118 @@

using Mathematics.NET.Core.Operations;
using Mathematics.NET.Core.Relations;
using Mathematics.NET.DifferentialGeometry;
using Mathematics.NET.DifferentialGeometry.Abstractions;
using Mathematics.NET.LinearAlgebra;

namespace Mathematics.NET.AutoDiff;

/// <summary>Defines support for dual numbers.</summary>
/// <typeparam name="T">The type that implements the interface.</typeparam>
/// <typeparam name="U">A type that implements <see cref="IComplex{T}"/> and <see cref="IDifferentiableFunctions{T}"/>.</typeparam>
public interface IDual<T, U>
: IAdditionOperation<T, T>,
IDivisionOperation<T, T>,
IMultiplicationOperation<T, T>,
IUnaryMinusOperation<T, T>,
IUnaryPlusOperation<T, T>,
ISubtractionOperation<T, T>,
/// <typeparam name="TDN">The type that implements the interface.</typeparam>
/// <typeparam name="TN">A type that implements <see cref="IComplex{T}"/> and <see cref="IDifferentiableFunctions{T}"/>.</typeparam>
public interface IDual<TDN, TN>
: IAdditionOperation<TDN, TDN>,
IDivisionOperation<TDN, TDN>,
IMultiplicationOperation<TDN, TDN>,
IUnaryMinusOperation<TDN, TDN>,
IUnaryPlusOperation<TDN, TDN>,
ISubtractionOperation<TDN, TDN>,
IFormattable,
IEqualityRelation<T, bool>,
IEquatable<T>,
IDifferentiableFunctions<T>
where T : IDual<T, U>
where U : IComplex<U>, IDifferentiableFunctions<U>
IEqualityRelation<TDN, bool>,
IEquatable<TDN>,
IDifferentiableFunctions<TDN>
where TDN : IDual<TDN, TN>
where TN : IComplex<TN>, IDifferentiableFunctions<TN>
{
/// <summary>Represents the primal part of the dual number.</summary>
U D0 { get; }
TN D0 { get; }

/// <summary>Represents the tangent part of the dual number.</summary>
U D1 { get; }
TN D1 { get; }

/// <summary>Create an instance of the type with a specified value.</summary>
/// <param name="value">A value.</param>
/// <returns>An instance of the type.</returns>
static abstract T CreateVariable(U value);
static abstract TDN CreateVariable(TN value);

/// <summary>Create an instance of the type with a specified value and seed.</summary>
/// <param name="value">A value.</param>
/// <param name="seed">A seed.</param>
/// <returns>An instance of the type.</returns>
static abstract T CreateVariable(U value, U seed);
static abstract TDN CreateVariable(TN value, TN seed);

/// <inheritdoc cref="IDifferentiableFunctions{T}.Pow(T, T)"/>
static abstract T Pow(T x, U y);
static abstract TDN Pow(TDN x, TN y);

/// <inheritdoc cref="IDifferentiableFunctions{T}.Pow(T, T)"/>
static abstract T Pow(U x, T y);
static abstract TDN Pow(TN x, TDN y);

/// <summary>Create a seeded instance of this type.</summary>
/// <param name="seed">The seed value.</param>
/// <returns>A seeded value.</returns>
T WithSeed(U seed);
TDN WithSeed(TN seed);

//
// DifGeo
//

/// <summary>Create an autodiff, rank-one tensor from vectors of initial and seed values.</summary>
/// <typeparam name="TI">An index.</typeparam>
/// <param name="x">A vector of initial values.</param>
/// <param name="seed">A vector of seed values.</param>
/// <returns>A rank-one tensor of two initial and seed values.</returns>
static abstract AutoDiffTensor2<TDN, TN, TI> CreateAutoDiffTensor<TI>(in Vector2<TN> x, in Vector2<TN> seed)
where TI : IIndex;

/// <summary>Create an autodiff, rank-one tensor from intial and seed values.</summary>
/// <typeparam name="TI">An index.</typeparam>
/// <param name="x0">The zeroth value.</param>
/// <param name="x1">The first value.</param>
/// <param name="seed0">The zeroth seed value.</param>
/// <param name="seed1">The first seed value.</param>
/// <returns>A rank-one tensor of two initial and seed values.</returns>
static abstract AutoDiffTensor2<TDN, TN, TI> CreateAutoDiffTensor<TI>(in TN x0, in TN x1, in TN seed0, in TN seed1)
where TI : IIndex;

/// <summary>Create an autodiff, rank-one tensor from vectors of initial and seed values.</summary>
/// <typeparam name="TI">An index.</typeparam>
/// <param name="x">A vector of initial values.</param>
/// <param name="seed">A vector of seed values.</param>
/// <returns>A rank-one tensor of three initial and seed values.</returns>
static abstract AutoDiffTensor3<TDN, TN, TI> CreateAutoDiffTensor<TI>(in Vector3<TN> x, in Vector3<TN> seed)
where TI : IIndex;

/// <summary>Create an autodiff, rank-one tensor from intial and seed values.</summary>
/// <typeparam name="TI">An index.</typeparam>
/// <param name="x0">The zeroth value.</param>
/// <param name="x1">The first value.</param>
/// <param name="x2">The second value.</param>
/// <param name="seed0">The zeroth seed value.</param>
/// <param name="seed1">The first seed value.</param>
/// <param name="seed2">The second seed value.</param>
/// <returns>A rank-one tensor of three initial and seed values.</returns>
static abstract AutoDiffTensor3<TDN, TN, TI> CreateAutoDiffTensor<TI>(in TN x0, in TN x1, in TN x2, in TN seed0, in TN seed1, in TN seed2)
where TI : IIndex;

/// <summary>Create an autodiff, rank-one tensor from vectors of initial and seed values.</summary>
/// <typeparam name="TI">An index.</typeparam>
/// <param name="x">A vector of initial values.</param>
/// <param name="seed">A vector of seed values.</param>
/// <returns>A rank-one tensor of four initial and seed values.</returns>
static abstract AutoDiffTensor4<TDN, TN, TI> CreateAutoDiffTensor<TI>(in Vector4<TN> x, in Vector4<TN> seed)
where TI : IIndex;

/// <summary>Create an autodiff, rank-one tensor from intial and seed values.</summary>
/// <typeparam name="TI">An index.</typeparam>
/// <param name="x0">The zeroth value.</param>
/// <param name="x1">The first value.</param>
/// <param name="x2">The second value.</param>
/// <param name="x3">The third value.</param>
/// <param name="seed0">The zeroth seed value.</param>
/// <param name="seed1">The first seed value.</param>
/// <param name="seed2">The second seed value.</param>
/// <param name="seed3">The third seed value.</param>
/// <returns>A rank-one tensor of four initial and seed values.</returns>
static abstract AutoDiffTensor4<TDN, TN, TI> CreateAutoDiffTensor<TI>(in TN x0, in TN x1, in TN x2, in TN x3, in TN seed0, in TN seed1, in TN seed2, in TN seed3)
where TI : IIndex;
}
Loading

0 comments on commit 971ed40

Please sign in to comment.