Module: Calc
- Defined in:
- ext/calc/calc.c,
lib/calc.rb,
lib/calc/c.rb,
lib/calc/q.rb,
lib/calc/numeric.rb,
lib/calc/version.rb
Defined Under Namespace
Classes: C, MathError, Numeric, Q
Constant Summary collapse
- BUILTINS1 =
builtins implemented as instance methods on Calc::Q or Calc::C
%i( abs acos acosh acot acoth acsc acsch agd appr arg asec asech asin asinh atan atan2 atanh bernoulli bit bround btrunc catalan ceil cfappr cfsim char cmp comb conj cos cosh cot coth csc csch den digit digits estr euler exp fact factor fcnt fib floor frac frem gcd gcdrem gd highbit hypot ilog ilog10 ilog2 im int inverse iroot iseven isimag isint ismult isodd isprime isqrt isreal isrel issq jacobi lcm lcmfact lfactor ln log lowbit ltol meq minv mmin mne mod near nextcand nextprime norm num perm pfact pix places pmod popcnt power prevcand prevprime ptest quo quomod re root round scale sec sech sgn sin sinh sqrt tan tanh trunc xor ).freeze
- BUILTINS2 =
builtins implemented as module methods on Calc
%i( avg config freebernoulli freeeuler hean hnrmod max min pi polar ssq sum version ).freeze
- ALL_BUILTINS =
BUILTINS1 + BUILTINS2
- VERSION =
"0.2.0".freeze
Class Method Summary collapse
-
.avg(*args) ⇒ Calc::Q, Calc::C
Average (arithmetic mean).
-
.C(*args) ⇒ Object
rubocop:disable Style/MethodName.
- .config ⇒ Object
-
.freebernoulli ⇒ nil
Frees memory used to store calculated bernoulli numbers.
-
.freeeuler ⇒ nil
Frees memory used to store calculated euler numbers.
-
.hmean(*args) ⇒ Calc::Q, Calc::C
Harmonic mean.
-
.hnrmod(v, h, n, r) ⇒ Calc::Q
Computer mod h * 2^n + r.
-
.max(*args) ⇒ Calc::Q
Maximum from provided values.
-
.min(*args) ⇒ Calc::Q
Minimum from provided values.
-
.pi(*args) ⇒ Calc::Q
Evaluates п (pi) to a specified accuracy.
-
.polar(*args) ⇒ Calc::Numeric
Returns a new complex (or real) number specified by modulus (radius) and argument (angle, in radians).
-
.poly(*args) ⇒ Calc::Numeric
Evaluate a polynomial.
-
.Q(*args) ⇒ Object
rubocop:disable Style/MethodName.
-
.ssq(*args) ⇒ Calc::C, Calc::Q
Returns the sum of squares.
- .sum(*args) ⇒ Object
-
.version ⇒ Object
Returns the calc version string.
Class Method Details
.avg(*args) ⇒ Calc::Q, Calc::C
Average (arithmetic mean)
Any number of numeric arguments can be provided. Returns the sum of all values divided by the number of values. If no values are provided, returns nil.
64 65 66 67 68 |
# File 'lib/calc.rb', line 64 def self.avg(*args) args.flatten! return nil if args.none? args.map { |n| to_calc_x(n) }.inject(:+) / args.size end |
.C(*args) ⇒ Object
rubocop:disable Style/MethodName
50 51 52 |
# File 'lib/calc.rb', line 50 def self.C(*args) # rubocop:disable Style/MethodName C.new(*args) end |
.config ⇒ Object
.freebernoulli ⇒ nil
Frees memory used to store calculated bernoulli numbers.
9 10 11 12 13 14 15 |
# File 'ext/calc/calc.c', line 9
static VALUE
calc_freebernoulli(VALUE self)
{
setup_math_error();
qfreebern();
return Qnil;
}
|
.freeeuler ⇒ nil
Frees memory used to store calculated euler numbers.
23 24 25 26 27 28 29 |
# File 'ext/calc/calc.c', line 23
static VALUE
calc_freeeuler(VALUE self)
{
setup_math_error();
qfreeeuler();
return Qnil;
}
|
.hmean(*args) ⇒ Calc::Q, Calc::C
Harmonic mean
Returns zero if any of the provded values is zero. Returns nil if no values are provided. Otherwise returns the harmonic mean of the given values.
79 80 81 82 83 84 |
# File 'lib/calc.rb', line 79 def self.hmean(*args) args.flatten! return nil if args.none? return Q::ZERO if args.detect(&:zero?) args.size / args.map { |n| to_calc_x(n) }.map(&:inverse).inject(:+) end |
.hnrmod(v, h, n, r) ⇒ Calc::Q
Computer mod h * 2^n + r
hnrmod(v, h, n, r) computes the value:
v % (h * 2^n + r)
where all parameters are integers and:
h > 0
n > 0
r == -1, 0 or 1
This is faster than standard mod.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'ext/calc/calc.c', line 51
static VALUE
calc_hnrmod(VALUE self, VALUE v, VALUE h, VALUE n, VALUE r)
{
NUMBER *qv, *qh, *qn, *qr, *qresult;
ZVALUE zresult;
setup_math_error();
qv = value_to_number(v, 0);
if (qisfrac(qv)) {
qfree(qv);
rb_raise(e_MathError, "1st arg of hnrmod (v) must be an integer");
}
qh = value_to_number(h, 0);
if (qisfrac(qh) || qisneg(qh) || qiszero(qh)) {
qfree(qv);
qfree(qh);
rb_raise(e_MathError, "2nd arg of hnrmod (h) must be an integer > 0");
}
qn = value_to_number(n, 0);
if (qisfrac(qn) || qisneg(qn) || qiszero(qn)) {
qfree(qv);
qfree(qh);
qfree(qn);
rb_raise(e_MathError, "3rd arg of hnrmod (n) must be an integer > 0");
}
qr = value_to_number(r, 0);
if (qisfrac(qr) || !zisabsleone(qr->num)) {
qfree(qv);
qfree(qh);
qfree(qn);
qfree(qr);
rb_raise(e_MathError, "4th arg of hnrmod (r) must be -1, 0 or 1");
}
zhnrmod(qv->num, qh->num, qn->num, qr->num, &zresult);
qresult = qalloc();
qresult->num = zresult;
return wrap_number(qresult);
}
|
.max(*args) ⇒ Calc::Q
Maximum from provided values.
Each argument must be convertable to Calc::Q. If no values, returns nil.
93 94 95 |
# File 'lib/calc.rb', line 93 def self.max(*args) args.compact.map { |n| Calc::Q(n) }.max end |
.min(*args) ⇒ Calc::Q
Minimum from provided values
Each argument must be convertable to Calc::Q. If no values, returns nil.
104 105 106 |
# File 'lib/calc.rb', line 104 def self.min(*args) args.compact.map { |n| Calc::Q(n) }.min end |
.pi(*args) ⇒ Calc::Q
Evaluates п (pi) to a specified accuracy
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'ext/calc/calc.c', line 100
static VALUE
calc_pi(int argc, VALUE * argv, VALUE self)
{
NUMBER *qepsilon, *qresult;
VALUE epsilon;
setup_math_error();
if (rb_scan_args(argc, argv, "01", &epsilon) == 0) {
qresult = qpi(conf->epsilon);
}
else {
qepsilon = value_to_number(epsilon, 1);
qresult = qpi(qepsilon);
qfree(qepsilon);
}
return wrap_number(qresult);
}
|
.polar(*args) ⇒ Calc::Numeric
Returns a new complex (or real) number specified by modulus (radius) and argument (angle, in radians).
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'ext/calc/calc.c', line 130
static VALUE
calc_polar(int argc, VALUE * argv, VALUE self)
{
VALUE radius, angle, epsilon, result;
NUMBER *qradius, *qangle, *qepsilon;
setup_math_error();
if (rb_scan_args(argc, argv, "21", &radius, &angle, &epsilon) == 3) {
qepsilon = value_to_number(epsilon, 1);
if (qisneg(qepsilon) || qiszero(qepsilon)) {
qfree(qepsilon);
rb_raise(e_MathError, "Negative or zero epsilon for polar");
}
}
else {
qepsilon = NULL;
}
qradius = value_to_number(radius, 0);
qangle = value_to_number(angle, 0);
result = wrap_complex(c_polar(qradius, qangle, qepsilon ? qepsilon : conf->epsilon));
if (qepsilon) {
qfree(qepsilon);
}
qfree(qradius);
qfree(qangle);
return result;
}
|
.poly(*args) ⇒ Calc::Numeric
Evaluate a polynomial
First case:
poly(a_0, a_1, ..., a_n, x)
returns:
a_n + (a_n-1 + ... + (a_1 + a_0 * x) * x ..) * x
In particular:
poly(a, x) -> a
poly(a, b, x) -> b + a * x
poly(a, b, c, x) -> c + (b + a * x) * x
or a*x**2 + b*x + c
In the second case, the first parameter is an array of coefficients, ie:
poly([a_0, a_1, ... a_n], x)
returns:
a_0 + (a_n-1 + (a_2 + ... a_n * x) * x)
Note that the order of coeffecients is reverse of the first case.
If one or more elements of clist is another array, and there is more than one argument (x, y, …) the coefficient corresponding to such an element is the value of the poly for that list and the next argument in x, y, … For example:
poly([[a, b, c], [d, e], f], x, y)
Returns:
(a + b * y + c * y^2) + (d + e * y) * x + f * x^2
For more explanation and examples on how the nested arrays works, see “help poly” bearning in mind that a calc list is equivament to a ruby array.
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/calc.rb', line 142 def self.poly(*args) raise ArgumentError, "Need at least one argument for poly" if args.none? if args.first.respond_to?(:each) # second case clist = args.shift evalpoly(clist, args.flatten, 0) else # first case x = to_calc_x(args.pop) return x if args.none? args.reverse.each_with_index.map { |coeff, i| to_calc_x(coeff) * x**i }.reduce(:+) end end |
.Q(*args) ⇒ Object
rubocop:disable Style/MethodName
46 47 48 |
# File 'lib/calc.rb', line 46 def self.Q(*args) # rubocop:disable Style/MethodName Q.new(*args) end |
.ssq(*args) ⇒ Calc::C, Calc::Q
Returns the sum of squares.
Nil values are ignored. If any argument is am array, it contributes the sum of squares of its contents recursively.
195 196 197 |
# File 'lib/calc.rb', line 195 def self.ssq(*args) args.flatten.map { |term| to_calc_x(term)**2 }.inject(:+) end |
.sum(*args) ⇒ Object
199 200 201 |
# File 'lib/calc.rb', line 199 def self.sum(*args) args.flatten.map { |t| to_calc_x(t) }.compact.inject(:+) end |
.version ⇒ Object
Returns the calc version string
This will return a string specifying the version of calc/libcalc which ruby-calc was compiled against.
For the version of ruby-calc itself, use ‘Calc::VERSION`.
168 169 170 171 172 |
# File 'ext/calc/calc.c', line 168
static VALUE
calc_version(VALUE self)
{
return rb_str_new_cstr(version());
}
|