summaryrefslogtreecommitdiffhomepage
path: root/src/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/math.c')
-rw-r--r--src/math.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/math.c b/src/math.c
index adf02206c..2d52faaca 100644
--- a/src/math.c
+++ b/src/math.c
@@ -10,6 +10,39 @@
#define domain_error(msg) \
mrb_raise(mrb, E_RANGE_ERROR, "Numerical argument is out of domain - " #msg);
+/* math functions not provided under Microsoft Visual C++ */
+#ifdef _MSC_VER
+#define asinh(x) log(x + sqrt(pow(x,2.0) + 1))
+#define acosh(x) log(x + sqrt(pow(x,2.0) - 1))
+#define atanh(x) (log(1+x) - log(1-x))/2.0
+#define cbrt(x) pow(x,1.0/3.0)
+
+
+double erf(double x)
+{
+ // constants
+ double a1 = 0.254829592;
+ double a2 = -0.284496736;
+ double a3 = 1.421413741;
+ double a4 = -1.453152027;
+ double a5 = 1.061405429;
+ double p = 0.3275911;
+
+ // Save the sign of x
+ int sign = 1;
+ if (x < 0)
+ sign = -1;
+ x = fabs(x);
+
+ // A&S formula 7.1.26
+ double t = 1.0/(1.0 + p*x);
+ double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
+
+ return sign*y;
+}
+
+#endif
+
mrb_value
mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
@@ -216,6 +249,62 @@ math_tanh(mrb_state *mrb, mrb_value obj)
/*
+ INVERSE HYPERBOLIC TRIG FUNCTIONS
+*/
+
+/*
+ * call-seq:
+ * Math.asinh(x) -> float
+ *
+ * Computes the inverse hyperbolic sine of <i>x</i>.
+ */
+static mrb_value
+math_asinh(mrb_state *mrb, mrb_value obj)
+{
+ mrb_float x;
+
+ mrb_get_args(mrb, "f", &x);
+
+ x = asinh(x);
+
+ return mrb_float_value(x);
+}
+
+/*
+ * call-seq:
+ * Math.acosh(x) -> float
+ *
+ * Computes the inverse hyperbolic cosine of <i>x</i>.
+ */
+static mrb_value
+math_acosh(mrb_state *mrb, mrb_value obj)
+{
+ mrb_float x;
+
+ mrb_get_args(mrb, "f", &x);
+ x = acosh(x);
+
+ return mrb_float_value(x);
+}
+
+/*
+ * call-seq:
+ * Math.atanh(x) -> float
+ *
+ * Computes the inverse hyperbolic tangent of <i>x</i>.
+ */
+static mrb_value
+math_atanh(mrb_state *mrb, mrb_value obj)
+{
+ mrb_float x;
+
+ mrb_get_args(mrb, "f", &x);
+ x = atanh(x);
+
+ return mrb_float_value(x);
+}
+
+/*
EXPONENTIALS AND LOGARITHMS
*/
#if defined __CYGWIN__
@@ -334,6 +423,49 @@ math_log10(mrb_state *mrb, mrb_value obj)
/*
* call-seq:
+ * Math.cbrt(numeric) -> float
+ *
+ * Returns the cube root of <i>numeric</i>.
+ *
+ * -9.upto(9) {|x|
+ * p [x, Math.cbrt(x), Math.cbrt(x)**3]
+ * }
+ * #=>
+ * [-9, -2.0800838230519, -9.0]
+ * [-8, -2.0, -8.0]
+ * [-7, -1.91293118277239, -7.0]
+ * [-6, -1.81712059283214, -6.0]
+ * [-5, -1.7099759466767, -5.0]
+ * [-4, -1.5874010519682, -4.0]
+ * [-3, -1.44224957030741, -3.0]
+ * [-2, -1.25992104989487, -2.0]
+ * [-1, -1.0, -1.0]
+ * [0, 0.0, 0.0]
+ * [1, 1.0, 1.0]
+ * [2, 1.25992104989487, 2.0]
+ * [3, 1.44224957030741, 3.0]
+ * [4, 1.5874010519682, 4.0]
+ * [5, 1.7099759466767, 5.0]
+ * [6, 1.81712059283214, 6.0]
+ * [7, 1.91293118277239, 7.0]
+ * [8, 2.0, 8.0]
+ * [9, 2.0800838230519, 9.0]
+ *
+ */
+static mrb_value
+math_cbrt(mrb_state *mrb, mrb_value obj)
+{
+ mrb_float x;
+
+ mrb_get_args(mrb, "f", &x);
+ x = cbrt(x);
+
+ return mrb_float_value(x);
+}
+
+
+/*
+ * call-seq:
* Math.frexp(numeric) -> [ fraction, exponent ]
*
* Returns a two-element array containing the normalized fraction (a
@@ -396,6 +528,43 @@ math_hypot(mrb_state *mrb, mrb_value obj)
return mrb_float_value(x);
}
+/*
+ * call-seq:
+ * Math.erf(x) -> float
+ *
+ * Calculates the error function of x.
+ */
+static mrb_value
+math_erf(mrb_state *mrb, mrb_value obj)
+{
+ mrb_float x;
+
+ mrb_get_args(mrb, "f", &x);
+ x = erf(x);
+
+ return mrb_float_value(x);
+}
+
+
+#ifndef _MSC_VER
+/*
+ * call-seq:
+ * Math.erfc(x) -> float
+ *
+ * Calculates the complementary error function of x.
+ */
+static mrb_value
+math_erfc(mrb_state *mrb, mrb_value obj)
+{
+ mrb_float x;
+
+ mrb_get_args(mrb, "f", &x);
+ x = erfc(x);
+
+ return mrb_float_value(x);
+}
+#endif
+
/* ------------------------------------------------------------------------*/
void
mrb_init_math(mrb_state *mrb)
@@ -428,13 +597,23 @@ mrb_init_math(mrb_state *mrb)
mrb_define_class_method(mrb, mrb_math, "cosh", math_cosh, 1);
mrb_define_class_method(mrb, mrb_math, "tanh", math_tanh, 1);
+ mrb_define_class_method(mrb, mrb_math, "asinh", math_asinh, 1);
+ mrb_define_class_method(mrb, mrb_math, "acosh", math_acosh, 1);
+ mrb_define_class_method(mrb, mrb_math, "atanh", math_atanh, 1);
+
mrb_define_class_method(mrb, mrb_math, "exp", math_exp, 1);
mrb_define_class_method(mrb, mrb_math, "log", math_log, -1);
mrb_define_class_method(mrb, mrb_math, "log2", math_log2, 1);
mrb_define_class_method(mrb, mrb_math, "log10", math_log10, 1);
+ mrb_define_class_method(mrb, mrb_math, "cbrt", math_cbrt, 1);
mrb_define_class_method(mrb, mrb_math, "frexp", math_frexp, 1);
mrb_define_class_method(mrb, mrb_math, "ldexp", math_ldexp, 2);
mrb_define_class_method(mrb, mrb_math, "hypot", math_hypot, 2);
+
+ mrb_define_class_method(mrb, mrb_math, "erf", math_erf, 1);
+#ifndef _MSC_VER
+ mrb_define_class_method(mrb, mrb_math, "erfc", math_erfc, 1);
+#endif
}