math

package
v3.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 10, 2018 License: BSD-3-Clause Imports: 8 Imported by: 0

Documentation

Overview

Package math implements various useful mathematical functions and constants.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Acos

func Acos(z, x *decimal.Big) *decimal.Big

Acos returns the arccosine, in radians, of x.

Range:

Input: -1 <= x <= 1
Output: 0 <= Acos(x) <= pi

Special cases:

Acos(NaN)  = NaN
Acos(±Inf) = NaN
Acos(x)    = NaN if x < -1 or x > 1
Acos(-1)   = pi
Acos(1)    = 0

func Asin

func Asin(z, x *decimal.Big) *decimal.Big

Asin returns the arcsine, in radians, of x.

Range:

Input: -1 <= x <= 1
Output: -pi/2 <= Asin(x) <= pi/2

Special cases:

Asin(NaN)  = NaN
Asin(±Inf) = NaN
Asin(x)    = NaN if x < -1 or x > 1
Asin(±1)   = ±pi/2

func Atan

func Atan(z, x *decimal.Big) *decimal.Big

Atan returns the arctangent, in radians, of x.

Range:

Input: all real numbers
Output: -pi/2 <= Atan(x) <= pi/2

Special cases:

Atan(NaN)  = NaN
Atan(±Inf) = ±x * pi/2

func Atan2

func Atan2(z, y, x *decimal.Big) *decimal.Big

Atan2 calculates arctan of y/x and uses the signs of y and x to determine the valid quadrant

Range:

y input: all real numbers
x input: all real numbers
Output: -pi < Atan2(y, x) <= pi

Special cases:

Atan2(NaN, NaN)      = NaN
Atan2(y, NaN)        = NaN
Atan2(NaN, x)        = NaN
Atan2(±0, x >=0)     = ±0
Atan2(±0, x <= -0)   = ±pi
Atan2(y > 0, 0)      = +pi/2
Atan2(y < 0, 0)      = -pi/2
Atan2(±Inf, +Inf)    = ±pi/4
Atan2(±Inf, -Inf)    = ±3pi/4
Atan2(y, +Inf)       = 0
Atan2(y > 0, -Inf)   = +pi
Atan2(y < 0, -Inf)   = -pi
Atan2(±Inf, x)       = ±pi/2
Atan2(y, x > 0)      = Atan(y/x)
Atan2(y >= 0, x < 0) = Atan(y/x) + pi
Atan2(y < 0, x < 0)  = Atan(y/x) - pi

func BinarySplit

func BinarySplit(z *decimal.Big, ctx decimal.Context, start, stop uint64, A, P, B, Q SplitFunc) *decimal.Big

BinarySplit sets z to the result of the binary splitting formula and returns z. The formula is defined as:

    ∞    a(n)p(0) ... p(n)
S = Σ   -------------------
    n=0  b(n)q(0) ... q(n)

It should only be used when the number of terms is known ahead of time. If start is not in [start, stop) or stop is not in (start, stop], BinarySplit will panic.

func BinarySplitDynamic

func BinarySplitDynamic(ctx decimal.Context, A, P, B, Q SplitFunc) *decimal.Big

BinarySplitDynamic sets z to the result of the binary splitting formula. It should be used when the number of terms is not known ahead of time. For more information, See BinarySplit.

func Ceil

func Ceil(z, x *decimal.Big) *decimal.Big

Ceil sets z to the least integer value greater than or equal to x and returns z.

func Cos

func Cos(z, x *decimal.Big) *decimal.Big

Cos returns the cosine, in radians, of x.

Range:

Input: all real numbers
Output: -1 <= Cos(x) <= 1

Special cases:

Cos(NaN)  = NaN
Cos(±Inf) = NaN

func E

func E(z *decimal.Big) *decimal.Big

E sets z to the mathematical constant e and returns z.

func Exp

func Exp(z, x *decimal.Big) *decimal.Big

Exp sets z to e ** x and returns z.

func Floor

func Floor(z, x *decimal.Big) *decimal.Big

Floor sets z to the greatest integer value less than or equal to x and returns z.

func Hypot

func Hypot(z, p, q *decimal.Big) *decimal.Big

Hypot sets z to Sqrt(p*p + q*q) and returns z.

func Lentz

func Lentz(z *decimal.Big, g Generator) *decimal.Big

Lentz sets z to the result of the continued fraction provided by the Generator and returns z. The continued fraction should be represented as such:

                     a1
f(x) = b0 + --------------------
                       a2
            b1 + ---------------
                          a3
                 b2 + ----------
                            a4
                      b3 + -----
                             ...

Or, equivalently:

             a1   a2   a3
f(x) = b0 + ---- ---- ----
             b1 + b2 + b3 + ···

If terms need to be subtracted, the a_N terms should be negative. To compute a continued fraction without b_0, divide the result by a_1.

If the first call to the Generator's Next method returns false, the result of Lentz is undefined.

Note: the accuracy of the result may be affected by the precision of intermediate results. If larger precision is desired it may be necessary for the Generator to implement the Lentzer interface and set a higher precision for f, Δ, C, and D.

Example (Phi)

This example demonstrates using Lentz by calculating the golden ratio, φ.

package main

import (
	"fmt"
	gmath "math"

	"github.com/ericlagergren/decimal"
	"github.com/ericlagergren/decimal/math"
)

var one = new(decimal.Big).SetUint64(1)

type phiGenerator struct{ ctx decimal.Context }

func (p phiGenerator) Context() decimal.Context { return p.ctx }

func (p phiGenerator) Next() bool {
	return true
}

func (p phiGenerator) Term() math.Term {
	return math.Term{A: one, B: one}
}

func (p phiGenerator) Lentz() (f, Δ, C, D, eps *decimal.Big) {
	// Add a little extra precision to C and D so we get an "exact" result after
	// rounding.
	f = decimal.WithPrecision(p.ctx.Precision)
	Δ = decimal.WithPrecision(p.ctx.Precision)
	C = decimal.WithPrecision(p.ctx.Precision)
	D = decimal.WithPrecision(p.ctx.Precision)
	eps = decimal.New(1, p.ctx.Precision)
	return f, Δ, C, D, eps
}

// Phi sets z to the golden ratio, φ, and returns z.
func Phi(z *decimal.Big) *decimal.Big {
	ctx := z.Context
	ctx.Precision++
	math.Wallis(z, phiGenerator{ctx: ctx})
	ctx.Precision--
	return ctx.Round(z)
}

// This example demonstrates using Lentz by calculating the golden ratio, φ.
func main() {
	z := decimal.WithPrecision(16)
	Phi(z)
	p := (1 + gmath.Sqrt(5)) / 2

	fmt.Printf(`
Go     : %g
Decimal: %s`, p, z)
}
Output:


Go     : 1.618033988749895
Decimal: 1.618033988749895
Example (Tan)
package main

import (
	"fmt"

	"github.com/ericlagergren/decimal"
	"github.com/ericlagergren/decimal/math"
)

type tanGenerator struct {
	ctx decimal.Context
	k   uint64
	a   *decimal.Big
	b   *decimal.Big
}

func (t tanGenerator) Next() bool {
	return true
}

func (t *tanGenerator) Term() math.Term {
	t.k += 2
	return math.Term{A: t.a, B: t.b.SetUint64(t.k)}
}

func (t *tanGenerator) Context() decimal.Context { return t.ctx }

// Tan sets z to the tangent of the radian argument x.
func Tan(z, x *decimal.Big) *decimal.Big {
	// Handle special cases like 0, Inf, and NaN.

	// In the continued fraction
	//
	//                z    z^2   z^2   z^2
	//     tan(z) = ----- ----- ----- -----
	//                1  -  3  -  5  -  7  - ···
	//
	// the terms are subtracted, so we need to negate "A"

	ctx := decimal.Context{Precision: z.Context.Precision + 1}
	x0 := ctx.Mul(new(decimal.Big), x, x)
	x0.Neg(x0)

	g := &tanGenerator{
		ctx: ctx,
		k:   1<<64 - 1,
		a:   x0,
		b:   new(decimal.Big),
	}

	// Since our fraction doesn't have a leading (b0) we need to divide our
	// result by a1.
	tan := ctx.Quo(z, x, math.Lentz(z, g))
	ctx.Precision--
	return ctx.Set(z, tan)
}

func main() {
	z := decimal.WithPrecision(17)
	x := decimal.New(42, 0)

	fmt.Printf("tan(42) = %s\n", Tan(z, x).Round(16))
}
Output:

tan(42) = 2.291387992437486

func Log

func Log(z, x *decimal.Big) *decimal.Big

Log sets z to the natural logarithm of x and returns z.

func Log10

func Log10(z, x *decimal.Big) *decimal.Big

Log10 sets z to the common logarithm of x and returns z.

func Pi

func Pi(z *decimal.Big) *decimal.Big

Pi sets z to the mathematical constant pi and returns z.

func Pow

func Pow(z, x, y *decimal.Big) *decimal.Big

Pow sets z to x**y and returns z.

func Sin

func Sin(z, x *decimal.Big) *decimal.Big

Sin returns the sine, in radians, of x.

Range:

Input: all real numbers
Output: -1 <= Sin(x) <= 1

Special cases:

Sin(NaN) = NaN
Sin(Inf) = NaN

func Sqrt

func Sqrt(z, x *decimal.Big) *decimal.Big

Sqrt sets z to the square root of x and returns z.

func Tan

func Tan(z, x *decimal.Big) *decimal.Big

Tan returns the tangent, in radians, of x.

Range:

Input: -pi/2 <= x <= pi/2
Output: all real numbers

Special cases:

Tan(NaN) = NaN
Tan(±Inf) = NaN

func Wallis

func Wallis(z *decimal.Big, g Generator) *decimal.Big

Wallis sets z to the result of the continued fraction provided by the Generator and returns z. The fraction is evaluated in a top-down manner, using the recurrence algorithm discovered by John Wallis. For more information on continued fraction representations, see the Lentz function.

Types

type Contexter

type Contexter interface {
	Context() decimal.Context
}

Contexter allows Generators to provide a different Context than z's. It's intended to be analogous to the relationship between, for example, Context.Mul and Big.Mul.

type Generator

type Generator interface {
	// Next returns true if there are future terms. Every call to Term—even the
	// first—must be preceded by a call to Next. In general, Generators should
	// always return true unless an exceptional condition occurs.
	Next() bool

	// Term returns the next term in the fraction. The caller must not modify
	// any of the Term's fields.
	Term() Term
}

Generator represents a continued fraction.

type Lentzer

type Lentzer interface {
	// Lentz provides the backing storage for a Generator passed to the Lentz
	// function.
	//
	// In Contexter isn't implemented, f, Δ, C, and D should have large enough
	// precision to provide a correct result, (See note for the Lentz function.)
	//
	// eps should be a sufficiently small decimal, likely 1e-15 or smaller.
	//
	// For more information, refer to "Numerical Recipes in C: The Art of
	// Scientific Computing" (ISBN 0-521-43105-5), pg 171.
	Lentz() (f, Δ, C, D, eps *decimal.Big)
}

Lentzer, if implemented, allows Generators to provide their own backing storage for the Lentz function.

type SplitFunc

type SplitFunc func(n uint64) *decimal.Big

SplitFunc returns the intermediate value for a given n. The returned decimal must not be modified by the caller and may only be valid until the next invocation of said function. This allows the implementation to conserve memory usage.

type Term

type Term struct {
	A, B *decimal.Big
}

Term is a specific term in a continued fraction. A and B correspond with the a and b variables of the typical representation of a continued fraction. An example can be seen in the book, “Numerical Recipes in C: The Art of Scientific Computing” (ISBN 0-521-43105-5) in figure 5.2.1 on page 169.

func (Term) String

func (t Term) String() string

type Walliser

type Walliser interface {
	// Wallis provides the backing storage for a Generator passed to the Wallis
	// function. See the Lentzer interface for more information.
	Wallis() (a, a1, b, b1, p, eps *decimal.Big)
}

Walliser is analogous to Lentzer, except it's for the Wallis function.

Directories

Path Synopsis
Package debug provides simple routines for debugging continued fractions.
Package debug provides simple routines for debugging continued fractions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL