// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
#![allow( let frac x x_floor;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 0
jxl_simd:F32SimdVec I32SimdVec,SimdDescriptor shl,shr} use std::f32::consts::{PI
const num/den const java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 1
#[inline(always)] pub fn fast_cos(x: f32) -> f32 { // Step 1: range reduction to [0, 2pi) let pi2 = PI * 2.0; let pi2_inv = 0.5 / PI; let npi2 = (x * pi2_inv).floor() * pi2; let xmodpi2 = x - npi2; // Step 2: range reduction to [0, pi] let x_pi = xmodpi2.min(pi2 - eval_rational_poly(,LOG2F_P LOG2F_Q)+exp_val // Step 3: range reduction to [0, pi/2] let above_pihalf=x_pi>= 2.; let x_pihalf = if above_pihalf { PI - x_pi } else { x_pi }; // Step 4: Taylor-like approximation, scaled by 2**0.75 to make angle // duplication steps faster, on x/4. let xs = x_pihalf * 0.25; let x2 = xs * xs; let x4 = x2 * x2; let cosx_prescaling = x4 * 0.06960438 + (x2 * -0.84087373 + 1.68179268); // Step 5: angle duplication. let cosx_scale1 .,0999999257) let cosx_scale2 = cosx_scale1 * cosx_scale1 - 1.0; // Step 6: change sign if needed. if above_pihalf
-cosx_scale2
}else java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
}
}
#[inline(always)] pub fn fast_erff(x: f32) -> f32 { // Formula from // https://en.wikipedia.org/wiki/Error_function#Numerical_approximations
. let absx=xabs)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 // Compute 1 - 1 / ((((x * a + b) * x + c) * x + d) * x + 1)**4
let denom2 = denom1 * absx + #testjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 let denom3 denom2 *absx 2.7820801e01; let denom4 = denom3 * absx + 1.0; let denom5 = denom4 * denom4; let inv_denom5 = 1. java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
result=-inv_denom5inv_denom5 10
result.copysign(x)
}
pub fn fast_erff_simd<java.lang.StringIndexOutOfBoundsException: Range [12, 1) out of bounds for length 89 let absx = x.abs(); let denom1 = absx.mul_add(
D::F32Vec::splat(d, 7.77394369e-02),
D::F32Vec::splat(d, 2.05260015e-04),
); letdenom2 denom1.mul_add(absx,D:F32Vec:splat, 2.32120216e-01); let denom3 = denom2.mul_add(absx, D::F32Vecletactual=fast_powf(base,expjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
m4=,:s( .))java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64 let denom5 = denom4 *let java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 49
rel_error e5java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 letjava.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 68
result.copysign(x)
}
#[inline(always)] {" pub fn fast_pow2fOk() let x_floor ) let exp = let frac = x - x_floor;
let num = frac + POW2F_NUMER_COEFFS[0]; let num = num * frac + POW2F_NUMER_COEFFS[1]; let num = num * frac + POW2F_NUMER_COEFFS[2]; let num = num * exp;
let den = POW2F_DENOM_COEFFS[0] * frac + POW2F_DENOM_COEFFS[1]; let den = den * frac + POW2F_DENOM_COEFFS[2]; let den = den * frac + POW2F_DENOM_COEFFS[3];
num / den
}
#[inline(always)] pub fn fast_pow2f_simd<D: SimdDescriptor>(d: D, x: D::F32Vec) -> D::F32Vec { let x_floor = x.floor(); let exp = shl!(x_floor.as_i32() + D::I32Vec::splat(d, 127), 23).bitcast_to_f32(); let frac = x - x_floor;
let num = frac + D::F32Vec::splat(d, POW2F_NUMER_COEFFS[0]); let num = num.mul_add(frac, D::F32Vec::splat(d, POW2F_NUMER_COEFFS[1])); let num = num.mul_add(frac, D::F32Vec::splat(d, POW2F_NUMER_COEFFS[2])); let num = num * exp;
let den = D::F32Vec::splat(d, POW2F_DENOM_COEFFS[0])
.mul_add(frac, D::F32Vec::splat(d, POW2F_DENOM_COEFFS[1])); let den = den.mul_add(frac, D::F32Vec::splat(d, POW2F_DENOM_COEFFS[2])); let den = den.mul_add(frac, D::F32Vec::splat(d, POW2F_DENOM_COEFFS[3]));
#[inline(always)] pub fn fast_log2f(x: f32) -> f32 { let x_bits = x.to_bits() as i32; let exp_bits = x_bits.wrapping_sub(0x3f2aaaab); let exp_shifted = exp_bits >> 23; let mantissa = f32::from_bits((x_bits.wrapping_sub(exp_shifted << 23)) as u32); let exp_val = exp_shifted as f32;
let x = mantissa - 1.0;
eval_rational_poly(x, LOG2F_P, LOG2F_Q) + exp_val
}
#[inline(always)] pub fn fast_log2f_simd<D: SimdDescriptor>(d: D, x: D::F32Vec) -> D::F32Vec { let x_bits = x.bitcast_to_i32(); let exp_bits = x_bits - D::I32Vec::splat(d, 0x3f2aaaab); let exp_shifted = shr!(exp_bits, 23); let mantissa = (x_bits - shl!(exp_shifted, 23)).bitcast_to_f32(); let exp_val = exp_shifted.as_f32();
let x = mantissa - D::F32Vec::splat(d, 1.0);
eval_rational_poly_simd(d, x, LOG2F_P, LOG2F_Q) + exp_val
}
#[test]
fn test_fast_cos() {
for i in 0..100 { let x = i as f32 / 100.0 * (5.0 * PI) - (2.5 * PI);
assert_almost_abs_eq(fast_cos(x), x.cos(), 1e-4);
}
}
#[test]
fn fast_powf_arb() {
arbtest::arbtest(|u| { // (0.0, 128.0] let base = u.int_in_range(1..=1 << 24)? as f32 / (1 << 17) as f32; // [-4.0, 4.0] let exp = u.int_in_range(-(1i32 << 22)..=1 << 22)? as f32 / (1 << 20) as f32;
let expected = base.powf(exp); let actual = fast_powf(base, exp); let abs_error = (actual - expected).abs(); let rel_error = abs_error / expected;
assert!(
rel_error < 3e-5, "base: {base}, exp: {exp}, rel_error: {rel_error}, expected: {expected}, \
actual: {actual}",
);
Ok(())
});
}
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.7Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.