Nerd_STF 3.0.0-beta1

This is a prerelease version of Nerd_STF.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Nerd_STF --version 3.0.0-beta1                
NuGet\Install-Package Nerd_STF -Version 3.0.0-beta1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nerd_STF" Version="3.0.0-beta1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Nerd_STF --version 3.0.0-beta1                
#r "nuget: Nerd_STF, 3.0.0-beta1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Nerd_STF as a Cake Addin
#addin nuget:?package=Nerd_STF&version=3.0.0-beta1&prerelease

// Install Nerd_STF as a Cake Tool
#tool nuget:?package=Nerd_STF&version=3.0.0-beta1&prerelease                

Nerd_STF

Nerd_STF is a multi-purpose library for .NET focused primarily on mathematics. It supports basically all versions of .NET has plenty of flexibility to let you do what you please with it.

Contents

Examples

Here's how to derive a polynomial in Nerd_STF:

using Nerd_STF.Mathematics.Equations;

Polynomial poly = new(2, 1, 3); // 2x^2 + x + 3
Polynomial derivative = poly.Derive();

Console.WriteLine(derivative);  // Output: 4x + 1

Here's how to get or set part of a number group:

Float3 xyz = (1, 2, 3);

Float2 xy = new(xyz["xy"]);
Float2 zy = new(xyz["zy"]);
double[] yxzy = [.. xyz["yxzy"]];

xyz["yz"] = [7, 8];
Console.WriteLine(xyz); // Output: (1, 7, 8)

Pretty easy, right?

How to Install

NuGet

You can install the package very easily with the NuGet Package Manager. The link to its NuGet page is here. You could install it by running a command:

# Do not include version flag to download the latest release.
dotnet add package Nerd_STF --version 3.0

or by including a package reference element in your project file:


<PackageReference Include="Nerd_STF" Version="3.0" />

Manual Reference

You could also manually reference the DLL for the project. Go to the releases page and select the library version and .NET target of your choice. At the time of writing, this project compiles to .NET Standard 1.3, 2.1, and .NET 7.0, but more may be added in the future.

Place the DLL somewhere you'll be able to reference later.

If you're using Visual Studio 2019 or 2022:

  • Right click the project icon in the hierarchy.
  • Go to Add > Project Reference
  • Click Browse and locate the DLL you saved earlier.
  • Click OK. You should be good to go!

Otherwise, you'll have to add a project reference element in your project file somewhere.

<Reference Include="Nerd_STF">
  <HintPath>path\to\your\download\Nerd_STF.3.0.NET7.0.dll</HintPath>
</Reference>

I found a bug!

I'm not surprised, I'm only one guy. Feel free to make an issue in the repository and I'll get to it when I can!

I'd like to contribute!

Well, I'd prefer to do most of the programming myself, but if anyone wants to submit a pull request, feel free! Stick to the version-specific branches, try not to make commits on the main branch.

When's your next release?

No idea. This is a pet project, so progress on this library will come and go. It was more than a year between versions 2.4.1 and 3.0. It's really whenever mood strikes, so just watch the project to see what the current status is.

Older Versions

3.0 has plenty of breaking changes from 2.4.1 (and the rest of the 2.x updates), so it's totally fine if you don't want to update. I'll keep the 2.x updates up for the long-term, no reason to remove them. As for the versions before 2.0, well, it wasn't even really a library at that point. Do with it what you will.

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 is compatible.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.1 is compatible.  netstandard1.2 was computed.  netstandard1.3 is compatible.  netstandard1.4 was computed.  netstandard1.5 was computed.  netstandard1.6 was computed.  netstandard2.0 was computed.  netstandard2.1 is compatible. 
.NET Framework net45 was computed.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen30 was computed.  tizen40 was computed.  tizen60 was computed. 
Universal Windows Platform uap was computed.  uap10.0 was computed. 
Windows Phone wpa81 was computed. 
Windows Store netcore was computed.  netcore45 was computed.  netcore451 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.0-beta2 81 11/25/2024
3.0.0-beta1 76 10/29/2024
2.4.1 255 7/17/2023
2.4.0 179 7/10/2023
2.3.2 278 3/9/2023
2.3.1.68 370 11/12/2022
2.3.1.52-alpha 244 10/31/2022 2.3.1.52-alpha is deprecated because it has critical bugs.
2.3.1.39-alpha 205 9/30/2022 2.3.1.39-alpha is deprecated because it has critical bugs.
2.3.0 442 8/2/2022
2.2.0 458 6/10/2022
2.1.2 457 5/2/2022
2.1.1 419 4/17/2022
2.1.0 439 4/17/2022
2.0.1 450 4/3/2022
2.0.0 440 4/3/2022

# Nerd_STF v3.0-beta1

Hi! Pretty much nothing has remained the same from version 2. There are plenty of breaking changes, and the betas will have plenty of missing features from 2.4.1. The betas will continue until every feature from 2.4.1 has been added to 3.0 or scrapped.

In the mean time, here's what's new.

## More Compatibility

Nerd_STF now targets several versions of .NET and .NET Standard, making it basically run anywhere. You can use [this website](https://dotnet.microsoft.com/en-us/platform/dotnet-standard#versions) to see what different versions of .NET Standard support, but if your project uses a version of .NET that was released in the last 10 years, chances are Nerd_STF supports it.

In addition, Nerd_STF uses some of the new C# features while still retaining older compatibility. If you want to use Nerd_STF in your .NET 8.0 project, you will reference the version of Nerd_STF compiled for .NET 7.0 and retain those fancy new interface features (among others) found in C# 11. Nullability support has been added to all versions of .NET that use C# 8 and above. And if I decide to use more new C# features for Nerd_STF, I'll just target another version of .NET.

## Committed to Doubles

Nerd_STF is a precision library, not one meant to be highly optimized at the sacrifice of precision. So I've decided to fully commit to doubles. The double groups are still called `Float2`, `Float3` and `Float4`, because `Double2` doesn't have quite the same ring to it now, does it? Hope it doesn't get too confusing.

But all math functions are now using doubles (with a few exceptions).

## 'w' Goes in Front Now

I think this is how it should have been. I was really breaking the rules of the alphabet before. Previously in a `Float4`, the `w` component was fourth. Now it is first. The order goes w, x, y, z. You know, how it should.

This means though that casting a `Float3` to a `Float4` will put the extra zero at the start, not the end (because `x` -> `x` in the cast).
```csharp
Float3  xyz = (5, 6, 7);
Float4 wxyz = xyz;       // Gives (0, 5, 6, 7)
```
This also means that truncating a `Float4` removes the front `w` first, giving some odd results.
```csharp
Float2  xy  = (10, 9);
Float4 wxyz = xy;       // Gives (0, 10, 9, 0)
```
```csharp
Float4 wxyz = (9, 8, 7, 6);
Float2  xy  = (Float2)wxyz; // Must be explicitly stated. Yields (8, 7)
```

But `x` always goes to `x` when casting between groups, same with the other variables. Hopefully that'll make more sense.

## Combination Indexers

One thing I've always been envious of was HLSL's ability to easily make a subset of a group.
```c++
float3 group = float3(1, 2, 3);
float2 part = group.yz;         // Like this.
```
And I had a crude version of this in Nerd_STF before, with properties for `XY`, `YZW`, and stuff like that. But you couldn't do things out of order (for example, you could never do `.ZY`). Also, the naming scheme would not make very much sense. `x` was always the first item Now, you can do it with an indexer.

```csharp
Float4 wxyz = (1, 2, 3, 4);
IEnumerable<double> zyx = wxyz["zyx"]; // Yields [ 4, 3, 2 ]
```

I think you get it, it makes sense. It returns an IEnumerable though, so support has been added in the group constructors to read data from an IEnumerable. You can also set things this way.

```csharp
Float4 wxyz = (1, 2, 3, 4);
wxyz["xy"] = [ 9, 8 ];      // Yields (9, 8, 3, 4)
```

You can also have duplicates. Why you would want duplicates is beyond me. And the order can be whatever you'd like.
```csharp
Float4 wxyz = (1, 2, 3, 4);
IEnumerable<double> nums = wxyz["wyyxzzwy"]; // Yields [ 1, 3, 3, 2, 4, 4, 1, 3 ]
```

## Better Equations

The previous equation system was just a delegate to a method. While it worked for unoptimized things, it won't automatically give precise results. So that system has been overhauled.

Now, every equation derives from the `IEquation` interface, which defines a few operators (most importantly the `Get(double)` method, which is intended to evaluate the equation at the given input). And there are multiple types. There's the base `Equation` type that replicates the method delegate it used to be, but there are also now `Polynomial` equations which specialize in... uh... polynomials, including `Quadratic` and `Linear` along with the dynamic `Polynomial` type.

The indexer is equivalent to calling the `Get(double)` method.

Creating your own is easy, simply derive from the interface and implement the methods required. You should never throw an exception if the two equations you are adding (or multiplying or whatever) are not the same type. If they cannot be combined in a nice way, you should default to the delegate-based approach. Here is an example:
```csharp
public IEquation Add(IEquation other) {
   if (other is YourEquation yourEqu) {
       // Properly add your two equations.
   } else {
       // Unknown other equation type, do a basic addition system.
       return new Equation(x => Get(x) + other.Get(x));
   }
}
```

And in practice, you should avoid referring to a general equation by its type. Go by the interface operators instead.
```csharp
double Fun(double x) => 0.5 * MathE.Sin(x);
Equation a = (Equation)Fun; // The traditional delegate approach from previous versions.
Polynomial b = new Polynomial(1, 5, 4); // x^2 + 5x + 4

IEquation c = a.Add(b).Multiply(2); // Result is technically an `Equation`, but we should not cast here.
```

## Renamed the `Mathf` class.

I chose that name because I thought Unity did it well, but I also intend for this project to be compatible with Unity. So I've renamed it to `MathE`. I'm still iffy on that name. I'll commit to one before this project goes out of beta, but it might change until then. Other ideas I'm considering are `Mathe` and `Math2`. Feel free to give your input!

## Support for `System.Drawing` types.

I've tried to use this library when working with Windows Forms a few times. Problem is, it sucks having to manually set the variables from `Point` and `Size`. So Nerd_STF 3.0 now does that for you, with implicit casts to and from both, along with their float variations.

**It's worth mentioning that `Float2` is a double group, while `PointF` is a float group. Data *will* be lost slightly when implicitly casting. Watch out!**

---

Anyway, that's most of the big changes! I don't know if I'll do the full changelog like I have before. It takes a really long time to compile for large updates. We'll see. Thanks for checking out the update and I hope you use it well (or wait for the release version, that's fine too)!