add log10, hyperbolic tan and inverse hyperbolic tan functions (#1898)
This commit is contained in:
@@ -747,6 +747,20 @@ enum InstructionTemplate {
|
|||||||
Neg(ArithmeticTerm, usize),
|
Neg(ArithmeticTerm, usize),
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "plus")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "plus")))]
|
||||||
Plus(ArithmeticTerm, usize),
|
Plus(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "acosh")))]
|
||||||
|
ACosh(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "asinh")))]
|
||||||
|
ASinh(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "atanh")))]
|
||||||
|
ATanh(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "cosh")))]
|
||||||
|
Cosh(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "sinh")))]
|
||||||
|
Sinh(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "tanh")))]
|
||||||
|
Tanh(ArithmeticTerm, usize),
|
||||||
|
#[strum_discriminants(strum(props(Arity = "1", Name = "log10")))]
|
||||||
|
Log10(ArithmeticTerm, usize),
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "bitwise_complement")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "bitwise_complement")))]
|
||||||
BitwiseComplement(ArithmeticTerm, usize),
|
BitwiseComplement(ArithmeticTerm, usize),
|
||||||
// control instructions
|
// control instructions
|
||||||
@@ -1407,9 +1421,30 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ATan(ref at, t) => {
|
&Instruction::ATan(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, atom!("atan"), arena, at, t)
|
arith_instr_unary_functor(h, atom!("atan"), arena, at, t)
|
||||||
}
|
}
|
||||||
|
&Instruction::ACosh(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("acosh"), arena, at, t)
|
||||||
|
}
|
||||||
|
&Instruction::ASinh(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("asinh"), arena, at, t)
|
||||||
|
}
|
||||||
|
&Instruction::ATanh(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("atanh"), arena, at, t)
|
||||||
|
}
|
||||||
|
&Instruction::Cosh(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("cosh"), arena, at, t)
|
||||||
|
}
|
||||||
|
&Instruction::Sinh(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("sinh"), arena, at, t)
|
||||||
|
}
|
||||||
|
&Instruction::Tanh(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("tanh"), arena, at, t)
|
||||||
|
}
|
||||||
&Instruction::Sqrt(ref at, t) => {
|
&Instruction::Sqrt(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, atom!("sqrt"), arena, at, t)
|
arith_instr_unary_functor(h, atom!("sqrt"), arena, at, t)
|
||||||
}
|
}
|
||||||
|
&Instruction::Log10(ref at, t) => {
|
||||||
|
arith_instr_unary_functor(h, atom!("log10"), arena, at, t)
|
||||||
|
}
|
||||||
&Instruction::Abs(ref at, t) => {
|
&Instruction::Abs(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, atom!("abs"), arena, at, t)
|
arith_instr_unary_functor(h, atom!("abs"), arena, at, t)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,6 +195,13 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
atom!("sin") => Ok(Instruction::Sin(a1, t)),
|
atom!("sin") => Ok(Instruction::Sin(a1, t)),
|
||||||
atom!("tan") => Ok(Instruction::Tan(a1, t)),
|
atom!("tan") => Ok(Instruction::Tan(a1, t)),
|
||||||
atom!("log") => Ok(Instruction::Log(a1, t)),
|
atom!("log") => Ok(Instruction::Log(a1, t)),
|
||||||
|
atom!("asinh") => Ok(Instruction::ASinh(a1, t)),
|
||||||
|
atom!("acosh") => Ok(Instruction::ACosh(a1, t)),
|
||||||
|
atom!("atanh") => Ok(Instruction::ATanh(a1, t)),
|
||||||
|
atom!("sinh") => Ok(Instruction::Sinh(a1, t)),
|
||||||
|
atom!("cosh") => Ok(Instruction::Cosh(a1, t)),
|
||||||
|
atom!("tanh") => Ok(Instruction::Tanh(a1, t)),
|
||||||
|
atom!("log10") => Ok(Instruction::Log10(a1, t)),
|
||||||
atom!("exp") => Ok(Instruction::Exp(a1, t)),
|
atom!("exp") => Ok(Instruction::Exp(a1, t)),
|
||||||
atom!("sqrt") => Ok(Instruction::Sqrt(a1, t)),
|
atom!("sqrt") => Ok(Instruction::Sqrt(a1, t)),
|
||||||
atom!("acos") => Ok(Instruction::ACos(a1, t)),
|
atom!("acos") => Ok(Instruction::ACos(a1, t)),
|
||||||
|
|||||||
@@ -1006,6 +1006,53 @@ pub(crate) fn atan(n1: Number) -> Result<f64, MachineStubGen> {
|
|||||||
unary_float_fn_template(n1, |f| f.atan())
|
unary_float_fn_template(n1, |f| f.atan())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn asinh(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
unary_float_fn_template(n1, |f| f.asinh())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn acosh(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
unary_float_fn_template(n1, |f| f.acosh())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn atanh(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
let stub_gen = || {
|
||||||
|
let is_atom = atom!("is");
|
||||||
|
functor_stub(is_atom, 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
|
||||||
|
|
||||||
|
try_numeric_result!(if f1 == 1.0 || f1 == -1.0 {
|
||||||
|
Err(EvalError::Undefined)
|
||||||
|
} else {
|
||||||
|
result_f(&Number::Float(OrderedFloat(f1.atanh())))
|
||||||
|
},
|
||||||
|
stub_gen)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn sinh(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
unary_float_fn_template(n1, |f| f.sinh())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn cosh(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
unary_float_fn_template(n1, |f| f.cosh())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn tanh(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
unary_float_fn_template(n1, |f| f.tanh())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn log10(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
|
unary_float_fn_template(n1, |f| f.log(10f64))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn sqrt(n1: Number) -> Result<f64, MachineStubGen> {
|
pub(crate) fn sqrt(n1: Number) -> Result<f64, MachineStubGen> {
|
||||||
if n1.is_negative() {
|
if n1.is_negative() {
|
||||||
@@ -1255,6 +1302,27 @@ impl MachineState {
|
|||||||
atom!("tan") => self.interms.push(Number::Float(OrderedFloat(
|
atom!("tan") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
drop_iter_on_err!(self, iter, tan(a1))
|
drop_iter_on_err!(self, iter, tan(a1))
|
||||||
))),
|
))),
|
||||||
|
atom!("cosh") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, cosh(a1))
|
||||||
|
))),
|
||||||
|
atom!("sinh") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, sinh(a1))
|
||||||
|
))),
|
||||||
|
atom!("tanh") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, tanh(a1))
|
||||||
|
))),
|
||||||
|
atom!("acosh") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, acosh(a1))
|
||||||
|
))),
|
||||||
|
atom!("asinh") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, asinh(a1))
|
||||||
|
))),
|
||||||
|
atom!("atanh") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, atanh(a1))
|
||||||
|
))),
|
||||||
|
atom!("log10") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
|
drop_iter_on_err!(self, iter, log10(a1))
|
||||||
|
))),
|
||||||
atom!("sqrt") => self.interms.push(Number::Float(OrderedFloat(
|
atom!("sqrt") => self.interms.push(Number::Float(OrderedFloat(
|
||||||
drop_iter_on_err!(self, iter, sqrt(a1))
|
drop_iter_on_err!(self, iter, sqrt(a1))
|
||||||
))),
|
))),
|
||||||
|
|||||||
@@ -930,6 +930,69 @@ impl Machine {
|
|||||||
|
|
||||||
self.machine_st.p += 1;
|
self.machine_st.p += 1;
|
||||||
}
|
}
|
||||||
|
&Instruction::ACosh(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, acosh(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
&Instruction::ASinh(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, asinh(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
&Instruction::ATanh(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, atanh(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
&Instruction::Cosh(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, cosh(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
&Instruction::Sinh(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, sinh(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
&Instruction::Tanh(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, tanh(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
|
&Instruction::Log10(ref a1, t) => {
|
||||||
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
|
||||||
|
try_or_throw_gen!(&mut self.machine_st, log10(n1))
|
||||||
|
));
|
||||||
|
|
||||||
|
self.machine_st.p += 1;
|
||||||
|
}
|
||||||
&Instruction::Float(ref a1, t) => {
|
&Instruction::Float(ref a1, t) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user