diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlTransformsEncoder.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlTransformsEncoder.cs
index d7c7b63b4b..f3565a75d9 100644
--- a/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlTransformsEncoder.cs
+++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/JxlTransformsEncoder.cs
@@ -3,9 +3,6 @@
namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Encoder;
-///
-/// TODO
-///
internal static class JxlTransformsEncoder
{
}
diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeArrayFactory{T}.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeArrayFactory{T}.cs
new file mode 100644
index 0000000000..8b14fad0d4
--- /dev/null
+++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeArrayFactory{T}.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+
+namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Encoder.Optimize;
+
+internal class JxlOptimizeArrayFactory(Configuration configuration, int length)
+ where T : unmanaged, INumber
+{
+ public JxlOptimizeArray CreateArray(T defaultValue = default) => new(configuration, length, defaultValue);
+}
diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeArray{T}.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeArray{T}.cs
new file mode 100644
index 0000000000..2a89b1cd4b
--- /dev/null
+++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeArray{T}.cs
@@ -0,0 +1,204 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Buffers;
+using System.Numerics;
+using System.Numerics.Tensors;
+
+namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Encoder.Optimize;
+
+internal struct JxlOptimizeArray : IDisposable
+ where T : unmanaged, INumber
+{
+ private readonly IMemoryOwner memoryOwner;
+ private readonly int length;
+ private readonly Configuration configuration;
+ private bool isDisposed;
+
+ public JxlOptimizeArray(Configuration configuration, int length, T value)
+ {
+ this.memoryOwner = configuration.MemoryAllocator.Allocate(length);
+ this.memoryOwner.Memory.Span.Fill(value);
+ this.length = length;
+ this.configuration = configuration;
+ }
+
+ public readonly Span Span => this.memoryOwner.Memory.Span;
+
+ public readonly ref T this[int index]
+ {
+ get
+ {
+ DebugGuard.MustBeLessThan(index, this.length, nameof(index));
+ return ref this.memoryOwner.Memory.Span[index];
+ }
+ }
+
+ public static JxlOptimizeArray operator +(JxlOptimizeArray a, JxlOptimizeArray b)
+ {
+ JxlOptimizeArray z = new(a.configuration, a.length, default);
+ TensorPrimitives.Add(a.Span, b.Span, z.Span);
+ return z;
+ }
+
+ public static JxlOptimizeArray operator -(JxlOptimizeArray a, JxlOptimizeArray b)
+ {
+ JxlOptimizeArray z = new(a.configuration, a.length, default);
+ TensorPrimitives.Subtract(a.Span, b.Span, z.Span);
+ return z;
+ }
+
+ public static JxlOptimizeArray operator *(T a, JxlOptimizeArray b)
+ {
+ JxlOptimizeArray z = new(b.configuration, b.length, default);
+ TensorPrimitives.Multiply(b.Span, a, z.Span);
+ return z;
+ }
+
+ public readonly T DotProduct(JxlOptimizeArray y) => TensorPrimitives.Dot(this.Span, y.Span);
+
+ public static JxlOptimizeArray OptimizeWithScaledConjugateGradientMethod(
+ JxlOptimizeArrayFactory factory,
+ JxlOptimizeFunction function,
+ JxlOptimizeArray w0,
+ T gradientNormalThreshold,
+ int maxIterations)
+ where T : unmanaged, INumber,
+ IBinaryFloatingPointIeee754
+ {
+ // These variable names look cryptic, but they're part of
+ // the Scaled Conjugate Gradient method. See the reference
+ // implementation:
+ // https://github.com/libjxl/libjxl/blob/main/lib/jxl/enc_optimize.h#L81-L188
+ int n = w0.length;
+ T rsqThreshold = gradientNormalThreshold * gradientNormalThreshold;
+
+ T sigma0 = T.CreateSaturating(0.0001);
+ T lMin = T.CreateSaturating(1.0e-15);
+ T lMax = T.CreateSaturating(1.0e15);
+
+ JxlOptimizeArray w = w0;
+
+ JxlOptimizeArray wp = factory.CreateArray();
+ JxlOptimizeArray r = factory.CreateArray();
+ JxlOptimizeArray rt = factory.CreateArray();
+ JxlOptimizeArray e = factory.CreateArray();
+ JxlOptimizeArray p = factory.CreateArray();
+
+ T psq = default;
+ T fp;
+ T D = default;
+ T d;
+ T m = default;
+ T a;
+ T b;
+ T s;
+ T t = default;
+
+ T fw = function(w, ref r);
+ T rsq = r.DotProduct(r);
+ e = r;
+ p = r;
+
+ T l = T.CreateSaturating(1.0);
+ bool success = true;
+ long nSuccess = 0;
+ long k = 0;
+
+ // Hot loop
+ while (k++ < maxIterations)
+ {
+ if (success)
+ {
+ m = -p.DotProduct(r);
+
+ if (m >= T.Zero)
+ {
+ p = r;
+ m = -p.DotProduct(r);
+ }
+
+ psq = p.DotProduct(p);
+ s = sigma0 / T.Sqrt(psq);
+ _ = function(w + (s * p), ref rt);
+ t = p.DotProduct(r - rt) / s;
+ }
+
+ d = t + (l * psq);
+ if (d <= T.Zero)
+ {
+ d = l * psq;
+ l -= t / psq;
+ }
+
+ a = -m / d;
+ wp = w + (a * p);
+ fp = function(wp, ref rt);
+
+ D = T.CreateSaturating(2.0) * (fp - fw) / (a * m);
+ if (D >= T.Zero)
+ {
+ success = true;
+ nSuccess++;
+ w = wp;
+ }
+ else
+ {
+ success = false;
+ }
+
+ if (success)
+ {
+ e = r;
+ r = rt;
+ rsq = r.DotProduct(r);
+ fw = fp;
+
+ if (rsq <= rsqThreshold)
+ {
+ break;
+ }
+ }
+
+ if (D < T.CreateSaturating(0.25))
+ {
+ l = T.Min(T.CreateSaturating(4) * l, lMax);
+ }
+ else if (D > T.CreateSaturating(0.75))
+ {
+ l = T.Max(T.CreateSaturating(0.25) * l, lMax);
+ }
+
+ if ((nSuccess % n) == 0)
+ {
+ p = r;
+ l = T.CreateSaturating(1.0);
+ }
+ else if (success)
+ {
+ b = (e - r).DotProduct(r) / m;
+ p = (b * p) + r;
+ }
+ }
+
+ // clean up
+ wp.Dispose();
+ r.Dispose();
+ rt.Dispose();
+ e.Dispose();
+ p.Dispose();
+
+ return w;
+ }
+
+ public void Dispose()
+ {
+ if (this.isDisposed)
+ {
+ return;
+ }
+
+ this.isDisposed = true;
+ this.memoryOwner.Dispose();
+ }
+}
diff --git a/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeFunction{T}.cs b/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeFunction{T}.cs
new file mode 100644
index 0000000000..be9533b148
--- /dev/null
+++ b/src/ImageSharp/Formats/Jxl/Processing/Encoder/Optimize/JxlOptimizeFunction{T}.cs
@@ -0,0 +1,9 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+
+namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Encoder.Optimize;
+
+internal delegate T JxlOptimizeFunction(JxlOptimizeArray a, ref JxlOptimizeArray b)
+ where T : unmanaged, INumber;