Skip to content

Commit

Permalink
Update documentation and remove the Number variants for First.
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmada committed Apr 3, 2024
1 parent 8590cfc commit 0f776bd
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 75 deletions.
28 changes: 21 additions & 7 deletions docs/articles/Extending-the-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ The transform operator can also take two parameters, as shown in the `ProductOfA
```csharp
public static T? ProductOfAdditions<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y)
where T : struct, IMultiplicativeIdentity<T, T>, IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>
=> x.IsEmpty
=> x.IsEmpty
? null
: Tensor.Aggregate<T, AddOperator<T>, ProductOperator<T>>(x, y);
```
Expand Down Expand Up @@ -372,9 +372,9 @@ This behaves similarly to `Sum()` but without propagating `NaN` values. This pri

Further variants of the `AggregateNumber()` method exist: `AggregateNumber2D()`, `AggregateNumber3D()`, and `AggregateNumber4D()`.

### IndexOfPredicate Method
### First Method

The `IndexOfPredicate()` method returns the index of the initial element in the span that adheres to a specified predicate operator.
The `First()` method returns the first element in the span that adheres to a specified predicate operator. It yields a nullable type, with `null` indicating that no item satisfying the predicate is found.

The predicate operator must adhere to one of the subsequent interfaces with `TResult` specified as a `bool`:

Expand Down Expand Up @@ -407,15 +407,29 @@ public interface ITernaryToScalarOperator<T1, T2, T3, TResult>
}
```

For instance, to obtain the index of the initial element greater than or equal to a specified scalar value, this library furnishes the following operation:
For instance, to obtain the first element greater than or equal to a specified scalar value, this library provides the following operation:

```csharp
public static int IndexOfGreaterThanOrEqual<T>(ReadOnlySpan<T> source, T value)
public static T? FirstGreaterThanOrEqual<T>(ReadOnlySpan<T> source, T value)
where T : struct, IComparisonOperators<T, T, bool>
=> Tensor.IndexOfPredicate<T, GreaterThanOrEqualAnyOperator<T>>(source, value);
=> Tensor.First<T, GreaterThanOrEqualAnyOperator<T>>(source, value);
```

It employs the `GreaterThanOrEqualAnyOperator`, which is vectorizable.
It uses the `GreaterThanOrEqualAnyOperator` operator, which is vectorizable, improving performance when vectorization is available.

### IndexOfFirst Method

The method `IndexOfFirst()`, works similarly to `First()`, but returning the first element in the span that adheres to a specified predicate operator. Returns `-1` if no item satisfying the predicate is found.

For instance, to obtain the index of the first element greater than or equal to a specified scalar value, this library provides the following operation:

```csharp
public static int IndexOfFirstGreaterThanOrEqual<T>(ReadOnlySpan<T> source, T value)
where T : struct, IComparisonOperators<T, T, bool>
=> Tensor.IndexOfFirst<T, GreaterThanOrEqualAnyOperator<T>>(source, value);
```

It uses exactly the same `GreaterThanOrEqualAnyOperator` operator as in the previous example.

## Operators Unsuitable for Vectorization

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void GlobalSetup()
[BenchmarkCategory("Short")]
[Benchmark]
public short? NetFabric_Short()
=> TensorOperations.FirstGreaterThanNumber<short>(arrayShort!, 0);
=> TensorOperations.FirstGreaterThan<short>(arrayShort!, 0);

[BenchmarkCategory("Int")]
[Benchmark(Baseline = true)]
Expand All @@ -65,7 +65,7 @@ public void GlobalSetup()
[BenchmarkCategory("Int")]
[Benchmark]
public int? NetFabric_Int()
=> TensorOperations.FirstGreaterThanNumber(arrayInt!, 0);
=> TensorOperations.FirstGreaterThan(arrayInt!, 0);

[BenchmarkCategory("Long")]
[Benchmark(Baseline = true)]
Expand All @@ -75,7 +75,7 @@ public void GlobalSetup()
[BenchmarkCategory("Long")]
[Benchmark]
public long? NetFabric_Long()
=> TensorOperations.FirstGreaterThanNumber(arrayLong!, 0L);
=> TensorOperations.FirstGreaterThan(arrayLong!, 0L);

[BenchmarkCategory("Half")]
[Benchmark(Baseline = true)]
Expand All @@ -85,7 +85,7 @@ public void GlobalSetup()
[BenchmarkCategory("Half")]
[Benchmark]
public Half? NetFabric_Half()
=> TensorOperations.FirstGreaterThanNumber<Half>(arrayHalf!, (Half)0);
=> TensorOperations.FirstGreaterThan<Half>(arrayHalf!, (Half)0);

[BenchmarkCategory("Float")]
[Benchmark(Baseline = true)]
Expand All @@ -95,7 +95,7 @@ public void GlobalSetup()
[BenchmarkCategory("Float")]
[Benchmark]
public float? NetFabric_Float()
=> TensorOperations.FirstGreaterThanNumber<float>(arrayFloat!, 0.0f);
=> TensorOperations.FirstGreaterThan<float>(arrayFloat!, 0.0f);

[BenchmarkCategory("Double")]
[Benchmark(Baseline = true)]
Expand All @@ -105,5 +105,5 @@ public void GlobalSetup()
[BenchmarkCategory("Double")]
[Benchmark]
public double? NetFabric_Double()
=> TensorOperations.FirstGreaterThanNumber(arrayDouble!, 0.0);
=> TensorOperations.FirstGreaterThan(arrayDouble!, 0.0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public int Baseline_Short()
[BenchmarkCategory("Short")]
[Benchmark]
public int NetFabric_Short()
=> TensorOperations.IndexOfFirstGreaterThanNumber<short>(arrayShort!, 0);
=> TensorOperations.IndexOfFirstGreaterThan<short>(arrayShort!, 0);

[BenchmarkCategory("Int")]
[Benchmark(Baseline = true)]
Expand All @@ -65,7 +65,7 @@ public int Baseline_Int()
[BenchmarkCategory("Int")]
[Benchmark]
public int NetFabric_Int()
=> TensorOperations.IndexOfFirstGreaterThanNumber(arrayInt!, 0);
=> TensorOperations.IndexOfFirstGreaterThan(arrayInt!, 0);

[BenchmarkCategory("Long")]
[Benchmark(Baseline = true)]
Expand All @@ -75,7 +75,7 @@ public int Baseline_Long()
[BenchmarkCategory("Long")]
[Benchmark]
public int NetFabric_Long()
=> TensorOperations.IndexOfFirstGreaterThanNumber(arrayLong!, 0L);
=> TensorOperations.IndexOfFirstGreaterThan(arrayLong!, 0L);

[BenchmarkCategory("Half")]
[Benchmark(Baseline = true)]
Expand All @@ -85,7 +85,7 @@ public int Baseline_Half()
[BenchmarkCategory("Half")]
[Benchmark]
public int NetFabric_Half()
=> TensorOperations.IndexOfFirstGreaterThanNumber<Half>(arrayHalf!, (Half)0);
=> TensorOperations.IndexOfFirstGreaterThan<Half>(arrayHalf!, (Half)0);

[BenchmarkCategory("Float")]
[Benchmark(Baseline = true)]
Expand All @@ -95,7 +95,7 @@ public int Baseline_Float()
[BenchmarkCategory("Float")]
[Benchmark]
public int NetFabric_Float()
=> TensorOperations.IndexOfFirstGreaterThanNumber<float>(arrayFloat!, 0.0f);
=> TensorOperations.IndexOfFirstGreaterThan<float>(arrayFloat!, 0.0f);

[BenchmarkCategory("Double")]
[Benchmark(Baseline = true)]
Expand All @@ -105,5 +105,5 @@ public int Baseline_Double()
[BenchmarkCategory("Double")]
[Benchmark]
public int NetFabric_Double()
=> TensorOperations.IndexOfFirstGreaterThanNumber(arrayDouble!, 0.0);
=> TensorOperations.IndexOfFirstGreaterThan(arrayDouble!, 0.0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static void FirstGreaterThan_Should_Succeed(int[] source, int value, int?
// arrange

// act
var result = TensorOperations.FirstGreaterThanNumber(source, value);
var result = TensorOperations.FirstGreaterThan(source, value);

// assert
Assert.Equal(expected, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static void IndexOfFirstGreaterThan_Should_Succeed(int[] source, int valu
// arrange

// act
var result = TensorOperations.IndexOfFirstGreaterThanNumber(source, value);
var result = TensorOperations.IndexOfFirstGreaterThan(source, value);

// assert
Assert.Equal(expected, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace NetFabric.Numerics.Tensors;

public static partial class Tensor
{
public static T? FirstNumber<T, TPredicateOperator>(ReadOnlySpan<T> x, T y)
public static T? First<T, TPredicateOperator>(ReadOnlySpan<T> x, T y)
where T : struct
where TPredicateOperator : struct, IBinaryToScalarOperator<T, T, bool>
=> FirstNumber<T, T, IdentityOperator<T>, TPredicateOperator>(x, y);
=> First<T, T, IdentityOperator<T>, TPredicateOperator>(x, y);

public static TTransformed? FirstNumber<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y)
public static TTransformed? First<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y)
where TSource : struct
where TTransformed : struct
where TTransformOperator : struct, IUnaryOperator<TSource, TTransformed>
Expand Down Expand Up @@ -71,13 +71,13 @@ public static partial class Tensor
}
}

public static T? FirstNumber<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z)
public static T? First<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z)
where T : struct
where TTransformOperator : struct, IBinaryOperator<T, T, T>
where TPredicateOperator : struct, IBinaryToScalarOperator<T, T, bool>
=> FirstNumber<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z);
=> First<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z);

public static TTransformed? FirstNumber<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z)
public static TTransformed? First<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z)
where T1 : struct
where T2 : struct
where TTransformed : struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace NetFabric.Numerics.Tensors;

public static partial class Tensor
{
public static T? FirstNumber<T, TPredicateOperator>(ReadOnlySpan<T> x, T y, T z)
public static T? First<T, TPredicateOperator>(ReadOnlySpan<T> x, T y, T z)
where T : struct
where TPredicateOperator : struct, ITernaryToScalarOperator<T, T, T, bool>
=> FirstNumber<T, T, IdentityOperator<T>, TPredicateOperator>(x, y, z);
=> First<T, T, IdentityOperator<T>, TPredicateOperator>(x, y, z);

public static TTransformed? FirstNumber<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y, TTransformed z)
public static TTransformed? First<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y, TTransformed z)
where TSource : struct
where TTransformed : struct
where TTransformOperator : struct, IUnaryOperator<TSource, TTransformed>
Expand Down Expand Up @@ -72,13 +72,13 @@ public static partial class Tensor
}
}

public static T? FirstNumber<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z, T w)
public static T? First<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z, T w)
where T : struct
where TTransformOperator : struct, IBinaryOperator<T, T, T>
where TPredicateOperator : struct, ITernaryToScalarOperator<T, T, T, bool>
=> FirstNumber<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z, w);
=> First<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z, w);

public static TTransformed? FirstNumber<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z, TTransformed w)
public static TTransformed? First<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z, TTransformed w)
where T1 : struct
where T2 : struct
where TTransformed : struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace NetFabric.Numerics.Tensors;

public static partial class Tensor
{
public static T? FirstNumber<T, TPredicateOperator>(ReadOnlySpan<T> x)
public static T? First<T, TPredicateOperator>(ReadOnlySpan<T> x)
where T : struct
where TPredicateOperator : struct, IUnaryToScalarOperator<T, bool>
=> FirstNumber<T, T, IdentityOperator<T>, TPredicateOperator>(x);
=> First<T, T, IdentityOperator<T>, TPredicateOperator>(x);

public static TTransformed? FirstNumber<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x)
public static TTransformed? First<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x)
where TSource : struct
where TTransformed : struct
where TTransformOperator : struct, IUnaryOperator<TSource, TTransformed>
Expand Down Expand Up @@ -70,13 +70,13 @@ public static partial class Tensor
}
}

public static T? FirstNumber<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y)
public static T? First<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y)
where T : struct
where TTransformOperator : struct, IBinaryOperator<T, T, T>
where TPredicateOperator : struct, IUnaryToScalarOperator<T, bool>
=> FirstNumber<T, T, T, TTransformOperator, TPredicateOperator>(x, y);
=> First<T, T, T, TTransformOperator, TPredicateOperator>(x, y);

public static TTransformed? FirstNumber<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y)
public static TTransformed? First<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y)
where T1 : struct
where T2 : struct
where TTransformed : struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace NetFabric.Numerics.Tensors;

public static partial class Tensor
{
public static int IndexOfFirstNumber<T, TPredicateOperator>(ReadOnlySpan<T> x, T y)
public static int IndexOfFirst<T, TPredicateOperator>(ReadOnlySpan<T> x, T y)
where T : struct
where TPredicateOperator : struct, IBinaryToScalarOperator<T, T, bool>
=> IndexOfFirstNumber<T, T, IdentityOperator<T>, TPredicateOperator>(x, y);
=> IndexOfFirst<T, T, IdentityOperator<T>, TPredicateOperator>(x, y);

public static int IndexOfFirstNumber<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y)
public static int IndexOfFirst<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y)
where TSource : struct
where TTransformed : struct
where TTransformOperator : struct, IUnaryOperator<TSource, TTransformed>
Expand Down Expand Up @@ -70,13 +70,13 @@ static int VectorOperation(ReadOnlySpan<TSource> x, TTransformed y)
}
}

public static int IndexOfFirstNumber<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z)
public static int IndexOfFirst<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z)
where T : struct
where TTransformOperator : struct, IBinaryOperator<T, T, T>
where TPredicateOperator : struct, IBinaryToScalarOperator<T, T, bool>
=> IndexOfFirstNumber<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z);
=> IndexOfFirst<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z);

public static int IndexOfFirstNumber<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z)
public static int IndexOfFirst<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z)
where T1 : struct
where T2 : struct
where TTransformed : struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace NetFabric.Numerics.Tensors;

public static partial class Tensor
{
public static int IndexOfFirstNumber<T, TPredicateOperator>(ReadOnlySpan<T> x, T y, T z)
public static int IndexOfFirst<T, TPredicateOperator>(ReadOnlySpan<T> x, T y, T z)
where T : struct
where TPredicateOperator : struct, ITernaryToScalarOperator<T, T, T, bool>
=> IndexOfFirstNumber<T, T, IdentityOperator<T>, TPredicateOperator>(x, y, z);
=> IndexOfFirst<T, T, IdentityOperator<T>, TPredicateOperator>(x, y, z);

public static int IndexOfFirstNumber<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y, TTransformed z)
public static int IndexOfFirst<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x, TTransformed y, TTransformed z)
where TSource : struct
where TTransformed : struct
where TTransformOperator : struct, IUnaryOperator<TSource, TTransformed>
Expand Down Expand Up @@ -71,13 +71,13 @@ static int VectorOperation(ReadOnlySpan<TSource> x, TTransformed y, TTransformed
}
}

public static int IndexOfFirstNumber<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z, T w)
public static int IndexOfFirst<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T z, T w)
where T : struct
where TTransformOperator : struct, IBinaryOperator<T, T, T>
where TPredicateOperator : struct, ITernaryToScalarOperator<T, T, T, bool>
=> IndexOfFirstNumber<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z, w);
=> IndexOfFirst<T, T, T, TTransformOperator, TPredicateOperator>(x, y, z, w);

public static int IndexOfFirstNumber<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z, TTransformed w)
public static int IndexOfFirst<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y, TTransformed z, TTransformed w)
where T1 : struct
where T2 : struct
where TTransformed : struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ namespace NetFabric.Numerics.Tensors;

public static partial class Tensor
{
public static int IndexOfFirstNumber<T, TPredicateOperator>(ReadOnlySpan<T> x)
public static int IndexOfFirst<T, TPredicateOperator>(ReadOnlySpan<T> x)
where T : struct
where TPredicateOperator : struct, IUnaryToScalarOperator<T, bool>
=> IndexOfFirstNumber<T, T, IdentityOperator<T>, TPredicateOperator>(x);
=> IndexOfFirst<T, T, IdentityOperator<T>, TPredicateOperator>(x);

public static int IndexOfFirstNumber<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x)
public static int IndexOfFirst<TSource, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<TSource> x)
where TSource : struct
where TTransformed : struct
where TTransformOperator : struct, IUnaryOperator<TSource, TTransformed>
Expand Down Expand Up @@ -69,13 +69,13 @@ static int VectorOperation(ReadOnlySpan<TSource> x)
}
}

public static int IndexOfFirstNumber<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y)
public static int IndexOfFirst<T, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T> x, ReadOnlySpan<T> y)
where T : struct
where TTransformOperator : struct, IBinaryOperator<T, T, T>
where TPredicateOperator : struct, IUnaryToScalarOperator<T, bool>
=> IndexOfFirstNumber<T, T, T, TTransformOperator, TPredicateOperator>(x, y);
=> IndexOfFirst<T, T, T, TTransformOperator, TPredicateOperator>(x, y);

public static int IndexOfFirstNumber<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y)
public static int IndexOfFirst<T1, T2, TTransformed, TTransformOperator, TPredicateOperator>(ReadOnlySpan<T1> x, ReadOnlySpan<T2> y)
where T1 : struct
where T2 : struct
where TTransformed : struct
Expand Down
Loading

0 comments on commit 0f776bd

Please sign in to comment.