public static int SolveCubic(float a, float b, float c, out float r0, out float r1, out float r2)
        {
            float p  = b - a * a / 3;
            float p3 = p * p * p;
            float q  = a * (2 * a * a - 9 * b) / 27 + c;
            float d  = q * q + 4 * p3 / 27;
            float s  = a / -3;

            if (d >= 0)
            {
                float z = MathF.Sqrt(d);
                float u = (-q + z) / 2;
                float v = (-q - z) / 2;
                u = MathF.Cbrt(u);
                v = MathF.Cbrt(v);

                r0 = s + u + v;
                Unsafe.SkipInit(out r1);
                Unsafe.SkipInit(out r2);
                return(1);
            }
            else
            {
                float u = MathF.Sqrt(p / -3);
                float v = MathF.Acos(-MathF.Sqrt(-27 / p3) * q / 2) / 3;
                float m = MathF.Cos(v);
                float n = MathF.Cos(v - MathF.PI / 2) * 1.732050808f;

                r0 = s + u * 2 * m;
                r1 = s + u * (-m - n);
                r2 = s + u * (-m + n);
                return(3);
            }
        }
예제 #2
0
    /// <summary>
    ///     Inverse formula for <see cref="RadiusToIntensity"/>
    /// </summary>
    public float IntensityToRadius(float totalIntensity, float slope, float maxIntensity)
    {
        // max radius to avoid being capped by max-intensity
        var r0 = maxIntensity / slope;

        // volume at r0
        var v0 = RadiusToIntensity(r0, slope);

        if (totalIntensity <= v0)
        {
            // maxIntensity is a non-issue, can use simple inverse formula
            return(MathF.Cbrt(3 * totalIntensity / (slope * MathF.PI)));
        }

        return(r0 * (MathF.Sqrt(12 * totalIntensity / v0 - 3) / 6 + 0.5f));
    }
예제 #3
0
        public static void CbrtTest()
        {
            var result = 0.0f; var value = 0.0f;

            for (var iteration = 0; iteration < MathTests.Iterations; iteration++)
            {
                result += MathF.Cbrt(value);
                value  += cbrtDelta;
            }

            var diff = MathF.Abs(cbrtExpectedResult - result);

            if (float.IsNaN(result) || (diff > MathTests.SingleEpsilon))
            {
                throw new Exception($"Expected Result {cbrtExpectedResult,10:g9}; Actual Result {result,10:g9}");
            }
        }
예제 #4
0
파일: OkLab.cs 프로젝트: still-scene/t3
        // From Linear to oklab
        public static Vector4 RgbAToOkLab(Vector4 c)
        {
            var l = 0.4122214708f * c.X + 0.5363325363f * c.Y + 0.0514459929f * c.Z;
            var m = 0.2119034982f * c.X + 0.6806995451f * c.Y + 0.1073969566f * c.Z;
            var s = 0.0883024619f * c.X + 0.2817188376f * c.Y + 0.6299787005f * c.Z;

            var l1 = MathF.Cbrt(l);
            var m1 = MathF.Cbrt(m);
            var s1 = MathF.Cbrt(s);

            return(new Vector4(
                       0.2104542553f * l1 + 0.7936177850f * m1 - 0.0040720468f * s1,
                       1.9779984951f * l1 - 2.4285922050f * m1 + 0.4505937099f * s1,
                       0.0259040371f * l1 + 0.7827717662f * m1 - 0.8086757660f * s1,
                       c.W
                       ));
        }
예제 #5
0
파일: cbrt.cs 프로젝트: 0xCM/arrows
 public static ref float cbrt(ref float src)
 {
     src = MathF.Cbrt(src);
     return(ref src);
 }
예제 #6
0
파일: cbrt.cs 프로젝트: 0xCM/arrows
 public static float cbrt(float src)
 => MathF.Cbrt(src);
예제 #7
0
 /// <inheritdoc cref="MathF.Cbrt(float)"/>
 public static float Cbrt(this float value) => MathF.Cbrt(value);
예제 #8
0
        public Test(Mode modeParam, TextWriter errorOutParam, TextWriter infoOutParam, Table table)
        {
            _table            = table;
            _mode             = modeParam;
            _errorOut         = errorOutParam;
            _infoOut          = infoOutParam;
            _failedOperations = new HashSet <string>();

            // Validate parsing, this whole program expects little endian
            {
                uint val = 1234567891;
                if (Convert.ToUInt32(ToBinary(Convert.ToUInt32(ToBinary(val), 2)), 2) != val)
                {
                    ReportError($"{nameof(ToBinary)} and back failed");
                }
            }

            for (int testIndex = 0; testIndex < _table.Data.Length; testIndex++)
            {
                for (int testResult = 0; testResult < (_table.Data[testIndex].results?.Length ?? 0); testResult++)
                {
                    var result  = _table.Data[testIndex].results[testResult];
                    var asFloat = To <uint, float>(result.i);
                    if (asFloat != result.f && !NaNAndBitsMatch(asFloat, result.f))
                    {
                        ReportError($"FAILED PARSING {ToBinary(result.i)} to value {result.f.ToString("G9", CultureInfo.InvariantCulture)}, expected {ToBinary(result.f)}");
                    }
                }
            }
            for (int testIndex = 0; testIndex < _table.Data.Length; testIndex++)
            {
                float value = To <uint, float>(_table.Data[testIndex].initialValue);

                // Certain operations are funneling tests into specific ranges of values
                // so we aren't just using them as is, that is dVal's purpose in this code

                StartValidation(value);
                Validate(testIndex, "BIN", value);
                Validate(testIndex, "+", value + 0.1735f);
                Validate(testIndex, "-", value - 17f);
                Validate(testIndex, "*", value * 7.7757f);
                Validate(testIndex, "/", value / 0.3353f);
                Validate(testIndex, "%", value % 7.0f);
                // MATHF
                Validate(testIndex, nameof(MathF.Abs), MathF.Abs(value));
                Validate(testIndex, nameof(MathF.Acos), MathF.Acos(value % 1f));
                Validate(testIndex, nameof(MathF.Acosh), MathF.Acosh(1f + MathF.Abs(value)));
                Validate(testIndex, nameof(MathF.Asin), MathF.Asin(value % 1f));
                Validate(testIndex, nameof(MathF.Asinh), MathF.Asinh(value));
                Validate(testIndex, nameof(MathF.Atan), MathF.Atan(value));
                Validate(testIndex, nameof(MathF.Atan2), MathF.Atan2(value, 0.17f));
                Validate(testIndex, nameof(MathF.Atanh), MathF.Atanh(value % 1f));
                Validate(testIndex, nameof(MathF.Cbrt), MathF.Cbrt(value));
                Validate(testIndex, nameof(MathF.Ceiling), MathF.Ceiling(value));
                Validate(testIndex, nameof(MathF.Cos), MathF.Cos(value));
                Validate(testIndex, nameof(MathF.Cosh), MathF.Cosh(value % 2f));
                Validate(testIndex, nameof(MathF.Exp), MathF.Exp(1f / value));
                Validate(testIndex, nameof(MathF.Floor), MathF.Floor(value));
                Validate(testIndex, nameof(MathF.FusedMultiplyAdd), MathF.FusedMultiplyAdd(value, 1.33f, -1.5f));
                Validate(testIndex, nameof(MathF.IEEERemainder), MathF.IEEERemainder(value, 25.78f));
                Validate(testIndex, nameof(MathF.Log), MathF.Log(MathF.Abs(value)));
                Validate(testIndex, nameof(MathF.Log) + "(x,y)", MathF.Log(MathF.Abs(value), 4f));
                Validate(testIndex, nameof(MathF.Log2), MathF.Log2(MathF.Abs(value)));
                Validate(testIndex, nameof(MathF.Log10), MathF.Log10(MathF.Abs(value)));
                Validate(testIndex, nameof(MathF.Pow), MathF.Pow(MathF.Abs(value) % 1E+23f, 1.7f));
                Validate(testIndex, nameof(MathF.ScaleB), MathF.ScaleB(value % 1E+23f, 2));
                Validate(testIndex, nameof(MathF.Sin), MathF.Sin(value));
                Validate(testIndex, nameof(MathF.Sinh), MathF.Sinh(value % 2f));
                Validate(testIndex, nameof(MathF.Sqrt), MathF.Sqrt(MathF.Abs(value)));
                Validate(testIndex, nameof(MathF.Tan), MathF.Tan(value));
                Validate(testIndex, nameof(MathF.Tanh), MathF.Tanh(value));
                Validate(testIndex, nameof(MathF.Max), MathF.Max(value, 0.9f));
                Validate(testIndex, nameof(MathF.MaxMagnitude), MathF.MaxMagnitude(value, -0.7f));
                Validate(testIndex, nameof(MathF.Min), MathF.Min(value, 307f));
                Validate(testIndex, nameof(MathF.MinMagnitude), MathF.MinMagnitude(value, -8.89f));
                Validate(testIndex, nameof(MathF.Round), MathF.Round(value));
                if (float.IsNaN(value) == false)
                {
                    Validate(testIndex, nameof(MathF.Sign), MathF.Sign(value));
                }
                Validate(testIndex, nameof(MathF.Truncate), MathF.Truncate(value));
                // MATH
                double valueAsDouble = value;
                Validate(testIndex, $"D.{nameof(Math.Abs)}", Math.Abs(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Acos)}", Math.Acos(valueAsDouble % 1d));
                Validate(testIndex, $"D.{nameof(Math.Acosh)}", Math.Acosh(1d + Math.Abs(valueAsDouble)));
                Validate(testIndex, $"D.{nameof(Math.Asin)}", Math.Asin(valueAsDouble % 1d));
                Validate(testIndex, $"D.{nameof(Math.Asinh)}", Math.Asinh(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Atan)}", Math.Atan(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Atan2)}", Math.Atan2(valueAsDouble, 0.17d));
                Validate(testIndex, $"D.{nameof(Math.Atanh)}", Math.Atanh(valueAsDouble % 1d));
                Validate(testIndex, $"D.{nameof(Math.Cbrt)}", Math.Cbrt(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Ceiling)}", Math.Ceiling(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Cos)}", Math.Cos(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Cosh)}", Math.Cosh(valueAsDouble % 2d));
                Validate(testIndex, $"D.{nameof(Math.Exp)}", Math.Exp(1d / valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Floor)}", Math.Floor(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.FusedMultiplyAdd)}", Math.FusedMultiplyAdd(valueAsDouble, 1.33d, -1.5d));
                Validate(testIndex, $"D.{nameof(Math.IEEERemainder)}", Math.IEEERemainder(valueAsDouble, 25.78d));
                Validate(testIndex, $"D.{nameof(Math.Log)}", Math.Log(Math.Abs(valueAsDouble)));
                Validate(testIndex, $"D.{nameof(Math.Log)}" + "(x,y)", Math.Log(Math.Abs(valueAsDouble), 4d));
                Validate(testIndex, $"D.{nameof(Math.Log2)}", Math.Log2(Math.Abs(valueAsDouble)));
                Validate(testIndex, $"D.{nameof(Math.Log10)}", Math.Log10(Math.Abs(valueAsDouble)));
                Validate(testIndex, $"D.{nameof(Math.Pow)}", Math.Pow(Math.Abs(valueAsDouble) % 1E+23d, 1.7d));
                Validate(testIndex, $"D.{nameof(Math.ScaleB)}", Math.ScaleB(valueAsDouble % 1E+23d, 2));
                Validate(testIndex, $"D.{nameof(Math.Sin)}", Math.Sin(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Sinh)}", Math.Sinh(valueAsDouble % 2d));
                Validate(testIndex, $"D.{nameof(Math.Sqrt)}", Math.Sqrt(Math.Abs(valueAsDouble)));
                Validate(testIndex, $"D.{nameof(Math.Tan)}", Math.Tan(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Tanh)}", Math.Tanh(valueAsDouble));
                Validate(testIndex, $"D.{nameof(Math.Max)}", Math.Max(valueAsDouble, 0.9d));
                Validate(testIndex, $"D.{nameof(Math.MaxMagnitude)}", Math.MaxMagnitude(valueAsDouble, -0.7d));
                Validate(testIndex, $"D.{nameof(Math.Min)}", Math.Min(valueAsDouble, 307d));
                Validate(testIndex, $"D.{nameof(Math.MinMagnitude)}", Math.MinMagnitude(valueAsDouble, -8.89d));
                Validate(testIndex, $"D.{nameof(Math.Round)}", Math.Round(valueAsDouble));
                if (float.IsNaN(value) == false)
                {
                    Validate(testIndex, $"D.{nameof(Math.Sign)}", Math.Sign(valueAsDouble));
                }
                Validate(testIndex, $"D.{nameof(Math.Truncate)}", Math.Truncate(valueAsDouble));
            }
        }