Class: Sollya::Function

Inherits:
Object
  • Object
show all
Defined in:
ext/sollya_rb.c

Instance Method Summary collapse

Methods inherited from Object

#!=, #&, #==, #concat, #inspect, #print, #to_s, #to_sollya, #|, #~

Instance Method Details

#*(other) ⇒ Object



2205
2206
2207
2208
# File 'ext/sollya_rb.c', line 2205

static VALUE sollyarb_object_mul(VALUE self, VALUE other)
{
	return sollyarb_autowrap_object(sollya_lib_mul(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
}

#**(other) ⇒ Object



2217
2218
2219
2220
# File 'ext/sollya_rb.c', line 2217

static VALUE sollyarb_object_pow(VALUE self, VALUE other)
{
	return sollyarb_autowrap_object(sollya_lib_pow(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
}

#+(other) ⇒ Object



2193
2194
2195
2196
# File 'ext/sollya_rb.c', line 2193

static VALUE sollyarb_object_add(VALUE self, VALUE other)
{
	return sollyarb_autowrap_object(sollya_lib_add(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
}

#-(other) ⇒ Object



2199
2200
2201
2202
# File 'ext/sollya_rb.c', line 2199

static VALUE sollyarb_object_sub(VALUE self, VALUE other)
{
	return sollyarb_autowrap_object(sollya_lib_sub(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
}

#-@Object



2223
2224
2225
2226
# File 'ext/sollya_rb.c', line 2223

static VALUE sollyarb_object_neg(VALUE self)
{
	return sollyarb_autowrap_object(sollya_lib_neg(sollyarb_object_rb2ref(self)));
}

#/(other) ⇒ Object



2211
2212
2213
2214
# File 'ext/sollya_rb.c', line 2211

static VALUE sollyarb_object_div(VALUE self, VALUE other)
{
	return sollyarb_autowrap_object(sollya_lib_div(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(other)));
}

#<(other) ⇒ Object



2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
# File 'ext/sollya_rb.c', line 2823

static VALUE sollyarb_object_cmp_less(VALUE self, VALUE other)
{
	sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
	sollya_obj_t x = sollyarb_object_rb2ref(self);
	sollya_obj_t r = sollya_lib_cmp_less(x, y);
	VALUE b;
	if (sollya_lib_is_true(r)) {
		b = Qtrue;
	} else if (sollya_lib_is_false(r)) {
		b = Qfalse;
	} else {
		b = Qnil;
	}
	sollya_lib_clear_obj(r);
	if (RB_NIL_P(b)) {
		rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
	}
	return b;
}

#<=(other) ⇒ Object



2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
# File 'ext/sollya_rb.c', line 2865

static VALUE sollyarb_object_cmp_less_equal(VALUE self, VALUE other)
{
	sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
	sollya_obj_t x = sollyarb_object_rb2ref(self);
	sollya_obj_t r = sollya_lib_cmp_less_equal(x, y);
	VALUE b;
	if (sollya_lib_is_true(r)) {
		b = Qtrue;
	} else if (sollya_lib_is_false(r)) {
		b = Qfalse;
	} else {
		b = Qnil;
	}
	sollya_lib_clear_obj(r);
	if (RB_NIL_P(b)) {
		rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
	}
	return b;
}

#>(other) ⇒ Object



2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
# File 'ext/sollya_rb.c', line 2844

static VALUE sollyarb_object_cmp_greater(VALUE self, VALUE other)
{
	sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
	sollya_obj_t x = sollyarb_object_rb2ref(self);
	sollya_obj_t r = sollya_lib_cmp_greater(x, y);
	VALUE b;
	if (sollya_lib_is_true(r)) {
		b = Qtrue;
	} else if (sollya_lib_is_false(r)) {
		b = Qfalse;
	} else {
		b = Qnil;
	}
	sollya_lib_clear_obj(r);
	if (RB_NIL_P(b)) {
		rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
	}
	return b;
}

#>=(other) ⇒ Object



2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
# File 'ext/sollya_rb.c', line 2886

static VALUE sollyarb_object_cmp_greater_equal(VALUE self, VALUE other)
{
	sollya_obj_t y = SOLLYARB_TO_SOLLYA(other);
	sollya_obj_t x = sollyarb_object_rb2ref(self);
	sollya_obj_t r = sollya_lib_cmp_greater_equal(x, y);
	VALUE b;
	if (sollya_lib_is_true(r)) {
		b = Qtrue;
	} else if (sollya_lib_is_false(r)) {
		b = Qfalse;
	} else {
		b = Qnil;
	}
	sollya_lib_clear_obj(r);
	if (RB_NIL_P(b)) {
		rb_raise(rb_eArgError, "comparison of %s with %s failed", rb_obj_classname(self), rb_obj_classname(other));
	}
	return b;
}

#absObject



2392
2393
2394
# File 'ext/sollya_rb.c', line 2392

static VALUE sollyarb_function_abs(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_abs(sollyarb_object_rb2ref(self)));
}

#apply_at(x, prec: prec) ⇒ MPFR #apply_at(x) ⇒ Sollya::Object

Overloads:



2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
# File 'ext/sollya_rb.c', line 2440

static VALUE sollyarb_function_apply_at(int argc, VALUE *argv, VALUE self) {
	VALUE v;
	VALUE kw;
	const ID kwkeys[1] = {id_prec};
	VALUE kwvalues[1] = {Qundef};
	mpfr_prec_t prec = -1;
	rb_scan_args(argc, argv, "1:", &v, &kw);
	if (!NIL_P(kw)) {
		rb_get_kwargs(kw, kwkeys, 0, 1, kwvalues);
		if (kwvalues[0] != Qundef) {
			prec = NUM2LL(kwvalues[0]);
		}
	}
	if (prec <= 0) {
		sollya_obj_t p = sollya_lib_get_prec();
		sollya_lib_get_constant_as_int64(&prec, p);
		sollya_lib_clear_obj(p);
	}

	if (RB_FLOAT_TYPE_P(v)) {
		mpfr_t mp;
		mpfr_init2(mp, 53);
		mpfr_set_d(mp, NUM2DBL(v), MPFR_RNDN);

		VALUE rbres = mpfrrb_alloc(c_MPFR);
		mpfr_ptr mpr = mpfrrb_rb2ref_ext(rbres);
		mpfr_init2(mpr, prec);

		sollya_lib_evaluate_function_at_point(mpr, sollyarb_object_rb2ref(self), mp, NULL);

		mpfr_clear(mp);
		return rbres;
	} else if (rb_obj_is_kind_of(v, c_MPFR)) {
		mpfr_ptr mp = mpfrrb_rb2ref_ext(v);

		VALUE rbres = mpfrrb_alloc(c_MPFR);
		mpfr_ptr mpr = mpfrrb_rb2ref_ext(rbres);
		mpfr_init2(mpr, prec);

		sollya_lib_evaluate_function_at_point(mpr, sollyarb_object_rb2ref(self), mp, NULL);

		return rbres;
	} else {
		return sollyarb_autowrap_object(sollya_lib_apply(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(v), NULL));
	}
}

#arityInteger?

Returns:



2915
2916
2917
2918
2919
2920
2921
2922
# File 'ext/sollya_rb.c', line 2915

static VALUE sollyarb_function_arity(VALUE self)
{
	int arity = 0;
	if (!sollya_lib_get_function_arity(&arity, sollyarb_object_rb2ref(self)) || arity < 1) {
		return Qnil;
	}
	return INT2NUM(arity);
}

#autodiff(n, itvl) ⇒ List<Function>

Computes the first 𝑛 derivatives of self at a point or over an interval.

Parameters:

  • n (Integer)

    the order or differentiation

  • itvl (Constant, Range)

    point or interval over which self is differentiated

Returns:



2712
2713
2714
2715
# File 'ext/sollya_rb.c', line 2712

static VALUE sollyarb_function_autodiff(VALUE self, VALUE n, VALUE itvl)
{
	return sollyarb_autowrap_object(sollya_lib_autodiff(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(n), SOLLYARB_TO_SOLLYA(itvl)));
}

#ceilObject



2396
2397
2398
# File 'ext/sollya_rb.c', line 2396

static VALUE sollyarb_function_ceil(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_ceil(sollyarb_object_rb2ref(self)));
}

#chebyshevform(n, itvl) ⇒ Object



2702
2703
2704
2705
# File 'ext/sollya_rb.c', line 2702

static VALUE sollyarb_function_chebyshevform(VALUE self, VALUE n, VALUE itvl)
{
	return sollyarb_autowrap_object(sollya_lib_chebyshevform(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(n), SOLLYARB_TO_SOLLYA(itvl)));
}

#childrenObject



2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
# File 'ext/sollya_rb.c', line 2965

static VALUE sollyarb_function_get_children(VALUE self)
{
	sollya_obj_t func = sollyarb_object_rb2ref(self);
	int arity = 1;
	sollya_lib_get_function_arity(&arity, func);
	VALUE ar = rb_ary_new_capa(arity);
	if (rb_class_of(self) == c_Freevariable) {
		return ar;
	}
	sollya_obj_t c;
	int m = 1;
	while (sollya_lib_get_nth_subfunction(&c, func, m++)) {
		rb_ary_push(ar, sollyarb_autowrap_object(c));
	}
	return ar;
}

#coeff(n) ⇒ Sollya::Constant

Returns the coefficient of dgree n of a polynomial. Returns 0 if self is not a polynomial.

Parameters:

  • n (Integer)

    coefficient degree

Returns:



2578
2579
2580
2581
2582
2583
2584
# File 'ext/sollya_rb.c', line 2578

static VALUE sollyarb_function_coeff(VALUE self, VALUE n) {
	int i = NUM2INT(n);
	sollya_obj_t j = sollya_lib_constant_from_int(i);
	sollya_obj_t r = sollya_lib_coeff(sollyarb_object_rb2ref(self), j); 
	sollya_lib_clear_obj(j);
	return sollyarb_autowrap_object(r);
}

#coerce(num) ⇒ Object



2907
2908
2909
2910
# File 'ext/sollya_rb.c', line 2907

static VALUE sollyarb_object_coerce(VALUE self, VALUE num)
{
	return rb_ary_new_from_args(2, rb_funcallv(num, id_to_sollya, 0, NULL), self);
}

#degreeInteger?

Returns the degree of the polynomial self.

Returns:



2554
2555
2556
2557
2558
2559
2560
2561
# File 'ext/sollya_rb.c', line 2554

static VALUE sollyarb_function_degree(VALUE self) {
	sollya_obj_t d = sollya_lib_degree(sollyarb_object_rb2ref(self));
	int r;
	int s = sollya_lib_get_constant_as_int(&r, d);
	sollya_lib_clear_obj(d);
	if (!s || r < 0) return Qnil;
	return INT2NUM(r);
}

#denominatorObject



2428
2429
2430
# File 'ext/sollya_rb.c', line 2428

static VALUE sollyarb_function_denominator(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_denominator(sollyarb_object_rb2ref(self)));
}

#diffFunction

Differentiation operator. Returns the symbolic derivative of the function self by the global free variable. If self represents a function symbol that is externally bound to some code by library, the derivative is performed as a symbolic annotation to the returned expression tree.

Returns:



2505
2506
2507
# File 'ext/sollya_rb.c', line 2505

static VALUE sollyarb_function_diff(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_diff(sollyarb_object_rb2ref(self)));
}

#dirtyfindzeros(itvl) ⇒ Sollya::List<Sollya::Range>

Returns a list of numerical values listing the zeros of self on an interval.

Parameters:

Returns:

See Also:



2697
2698
2699
2700
# File 'ext/sollya_rb.c', line 2697

static VALUE sollyarb_function_dirtyfindzeros(VALUE self, VALUE itvl)
{
	return sollyarb_autowrap_object(sollya_lib_dirtyfindzeros(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
}

#dirtyintegral(itvl) ⇒ Sollya::Constant

Computes a numerical approximation of the integral of self on an interval.

The interval must be bound. If the interval contains one of -Inf or +Inf, the result is NaN, even if the integral has a meaning.

The result of this command depends on the global variables Sollya.prec and Sollya.points. The method used is the trapezium rule applied at 𝑛 evenly distributed points in the interval, where 𝑛 is the value of global variable Sollya.points.

This command computes a numerical approximation of the exact value of the integral. It should not be used if safety is critical. In this case, use command integral instead.

Warning: this command is currently known to be unsatisfactory. If you really need to compute integrals, think of using another tool.

Parameters:

Returns:



2623
2624
2625
2626
# File 'ext/sollya_rb.c', line 2623

static VALUE sollyarb_function_dirtyintegral(VALUE self, VALUE itvl)
{
	return sollyarb_autowrap_object(sollya_lib_dirtyintegral(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
}

#dirtysimplifyFunction

Simplifies constant subexpressions of self Those constant subexpressions are evaluated using floating-point arithmetic with the global precision Sollya.prec.

Returns:



2546
2547
2548
2549
# File 'ext/sollya_rb.c', line 2546

static VALUE sollyarb_function_dirtysimplify(VALUE self)
{
	return sollyarb_autowrap_object(sollya_lib_dirtysimplify(sollyarb_object_rb2ref(self)));
}

#evaluate(x) ⇒ Constant, ...

Evaluates self at a constant point or in a range

Parameters:

Returns:



2721
2722
2723
2724
# File 'ext/sollya_rb.c', line 2721

static VALUE sollyarb_function_evaluate(VALUE self, VALUE x)
{
	return sollyarb_autowrap_object(sollya_lib_evaluate(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(x)));
}

#expandFunction

Expands polynomial subexpressiosns. Expands all polynomial subexpressions in function self as far as possible. Factors of sums are multiplied out, power operators with constant positive integer exponents are replaced by multiplications.

Returns:



2527
2528
2529
# File 'ext/sollya_rb.c', line 2527

static VALUE sollyarb_function_expand(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_expand(sollyarb_object_rb2ref(self)));
}

#findzeros(itvl) ⇒ Sollya::List<Sollya::Range>

Returns a list of intervals containing all zeros of self on an interval.

Returns a list of intervals 𝐼1, ..., 𝐼𝑛 such that, for every zero 𝑧 of self , there exists some π‘˜ such that 𝑧 ∈ πΌπ‘˜ .

The list may contain intervals πΌπ‘˜ that do not contain any zero of self. An interval Ik may contain many zeros of self.

This command is meant for cases when safety is critical. If you want to be sure not to forget any zero, use findzeros. However, if you just want to know numerical values for the zeros of self, dirtyfindzeros should be quite satisfactory and a lot faster.

If 𝛿 denotes the value of global variable diam, the algorithm ensures that for each π‘˜, |πΌπ‘˜| ≀ 𝛿·|𝐼|.

The algorithm used is basically a bisection algorithm. It is the same algorithm that the one used for infnorm. See the help page of this command for more details. In short, the behavior of the algorithm depends on global variables prec, diam, taylorrecursions and hopitalrecursions.

Parameters:

Returns:

See Also:



2687
2688
2689
2690
# File 'ext/sollya_rb.c', line 2687

static VALUE sollyarb_function_findzeros(VALUE self, VALUE itvl)
{
	return sollyarb_autowrap_object(sollya_lib_findzeros(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
}

#floorObject



2400
2401
2402
# File 'ext/sollya_rb.c', line 2400

static VALUE sollyarb_function_floor(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_floor(sollyarb_object_rb2ref(self)));
}

#hornerFunction

Brings all polynomial subexpressions of self to Horner form.

This method rewrites the expression representing the function self in a way such that all polynomial subexpressions (or the whole expression itself, if it is a polynomial) are written in Horner form. The command horner does not endanger the safety of computations even in Sollya's floating-point environment: the function returned is mathematically equal to self.

Returns:



2517
2518
2519
# File 'ext/sollya_rb.c', line 2517

static VALUE sollyarb_function_horner(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_horner(sollyarb_object_rb2ref(self)));
}

#in(range) ⇒ Object



2187
2188
2189
2190
# File 'ext/sollya_rb.c', line 2187

static VALUE sollyarb_object_in(VALUE self, VALUE range)
{
	return sollyarb_autowrap_object(sollya_lib_negate(sollyarb_object_rb2ref(self)));
}

#integral(itvl) ⇒ Sollya::Range

Computes an interval bounding the integral of a function on an interval.

Returns an interval 𝐽 such that the exact value of the integral of self on I lies in 𝐽.

This command is safe but very inefficient. Use #dirtyintegral if you just want an approximate value.

The result of this command depends on the global variable Sollya.diam. The method used is the following: I is cut into intervals of length not greater then 𝛿 Β· |𝐼| where 𝛿 is the value of global variable Sollya.diam. On each small interval J, an evaluation of _self_f by interval is performed. The result is multiplied by the length of J. Finally all values are summed.

Parameters:

Returns:



2600
2601
2602
2603
# File 'ext/sollya_rb.c', line 2600

static VALUE sollyarb_function_integral(VALUE self, VALUE itvl)
{
	return sollyarb_autowrap_object(sollya_lib_integral(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl)));
}

#nearestintObject



2404
2405
2406
# File 'ext/sollya_rb.c', line 2404

static VALUE sollyarb_function_nearestint(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_nearestint(sollyarb_object_rb2ref(self)));
}

#nth_child(n) ⇒ Object



2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
# File 'ext/sollya_rb.c', line 2952

static VALUE sollyarb_function_get_nth_child(VALUE self, VALUE n)
{
	int m = NUM2INT(n);
	sollya_obj_t c;
	if (!sollya_lib_get_nth_subfunction(&c, sollyarb_object_rb2ref(self), m - 1)) {
		return Qnil;
	}
	if (rb_class_of(self) == c_Freevariable) {
		return Qnil;
	}
	return sollyarb_autowrap_object(c);
}

#numberroots(itvl) ⇒ Integer?

Computes the number of roots of a polynomial in a given range.

Rigorously computes the number of roots of polynomial self in the interval itvl. The technique used is Sturm's algorithm. The value returned is not just a numerical estimation of the number of roots of self in itvl: it is the exact number of roots.

The method #findzeros computes safe enclosures of all the zeros of a function, without forgetting any, but it is not guaranteed to separate them all in distinct intervals. numberroots is more accurate since it guarantees the exact number of roots. However, it does not compute them. It may be used, for instance, to certify that #findzeros did not put two distinct roots in the same interval.

Multiple roots are counted only once.

The interval itvl must be bounded. The algorithm cannot handle unbounded intervals. Moreover, the interval is considered as a closed interval: if one (or both) of the endpoints of itvl are roots of self, they are counted.

self can be any expression, but if Sollya fails to prove that it is a polynomial an error is produced. Also, please note that if the coefficients of self or the endpoints of itvl are not exactly representable, they are first numerically evaluated, before the algorithm is used. In that case, the counted number of roots corresponds to the rounded polynomial on the rounded interval and not to the exact parameters given by the user. A warning is displayed to inform the user.

Parameters:

Returns:



2655
2656
2657
2658
2659
2660
2661
2662
2663
# File 'ext/sollya_rb.c', line 2655

static VALUE sollyarb_function_numberroots(VALUE self, VALUE itvl)
{
	sollya_obj_t r = sollya_lib_numberroots(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(itvl));
	int64_t i;
	int s = sollya_lib_get_constant_as_int64(&i, r);
	sollya_lib_clear_obj(r);
	if (!s) return Qnil;
	return LL2NUM(i);
}

#numeratorObject



2424
2425
2426
# File 'ext/sollya_rb.c', line 2424

static VALUE sollyarb_function_numerator(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_numerator(sollyarb_object_rb2ref(self)));
}

#simplifyFunction

Simplifies an expression representing a function. It does not endanger the safety of computations even in Sollya's floating-point environment: the function returned is mathematically equal to self. Remark that the simplification provided by simplify is not perfect: they may exist simpler equivalent expressions for expressions returned by simplify.

Returns:



2538
2539
2540
# File 'ext/sollya_rb.c', line 2538

static VALUE sollyarb_function_simplify(VALUE self) {
	return sollyarb_autowrap_object(sollya_lib_simplify(sollyarb_object_rb2ref(self)));
}

#substitute(g) ⇒ Function, Constant

Replace the occurrences of the free variable in self.

Parameters:

Returns:



2730
2731
2732
2733
# File 'ext/sollya_rb.c', line 2730

static VALUE sollyarb_function_substitute(VALUE self, VALUE g)
{
	return sollyarb_autowrap_object(sollya_lib_substitute(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(g)));
}

#taylor(degree, point) ⇒ Function

Return the Taylor expansion of self in a point.

Parameters:

  • degree (Integer)

    degree of the expansion to be delivered

  • point (Constant)

    point in wich the function is to be developed

Returns:



2568
2569
2570
2571
# File 'ext/sollya_rb.c', line 2568

static VALUE sollyarb_function_taylor(VALUE self, VALUE degree, VALUE point)
{
	return sollyarb_autowrap_object(sollya_lib_taylor(sollyarb_object_rb2ref(self), SOLLYARB_TO_SOLLYA(degree), SOLLYARB_TO_SOLLYA(point)));
}