%mathpiper,def="^"

/* Faster version of raising power to 0.5 */
50 # _x ^ (1/2) <-- Sqrt(x);
50 # (x_IsPositiveNumber ^ (1/2))_IsInteger(SqrtN(x)) <-- SqrtN(x);
58 # 1 ^ n_IsInfinity <-- Undefined;
59 # _x ^ 1 <-- x;
59 # 1 ^ _n <-- 1;
59 # x_IsZero ^ y_IsZero <-- Undefined;
60 # (x_IsZero ^ n_IsRationalOrNumber)_(n>0) <-- 0;
60 # (x_IsZero ^ n_IsRationalOrNumber)_(n<0) <-- Infinity;
// This is to fix:
// In> 0.0000^2
// Result: 0.0000^2;
// In> 0.0^2/2
// Result: 0.0^2/2;
//60 # (x_IsNumber ^ n_IsRationalOrNumber)_(x+1=1) <-- 0;

59 # _x ^ Undefined <-- Undefined;
59 # Undefined ^ _x <-- Undefined;

/* Regular raising to the power. */
61 # Infinity ^ (y_IsNegativeNumber) <-- 0;
61 # (-Infinity) ^ (y_IsNegativeNumber) <-- 0;
//61 # x_IsPositiveNumber ^ y_IsPositiveNumber <-- PowerN(x,y);
//61 # x_IsPositiveNumber ^ y_IsNegativeNumber <-- (1/PowerN(x,-y));
// integer powers are very fast
61 # x_IsPositiveNumber ^ y_IsPositiveInteger <-- MathIntPower(x,y);
61 # x_IsPositiveNumber ^ y_IsNegativeInteger <-- 1/MathIntPower(x,-y);
65 # (x_IsPositiveNumber ^ y_IsNumber)_InNumericMode() <-- Exp(y*Ln(x));

90 # (-_x)^m_IsEven <-- x^m;
91 # (x_IsConstant ^ (m_IsOdd / p_IsOdd))_(IsNegativeNumber(Re(N(Eval(x))))) <--
     -((-x)^(m/p));
92 # (x_IsNegativeNumber ^ y_IsNumber)_InNumericMode() <-- Exp(y*Ln(x));


70  # (_x ^ m_IsRationalOrNumber) ^ n_IsRationalOrNumber <-- x^(n*m);

80 # (x_IsNumber/y_IsNumber) ^ n_IsPositiveInteger <-- x^n/y^n;
80 # (x_IsNumber/y_IsNumber) ^ n_IsNegativeInteger <-- y^(-n)/x^(-n);
80 # x_IsNegativeNumber ^ n_IsEven <-- (-x)^n;
80 # x_IsNegativeNumber ^ n_IsOdd <-- -((-x)^n);


100  # ((_x)*(_x ^ _m)) <-- x^(m+1);
100  # ((_x ^ _m)*(_x)) <-- x^(m+1);
100  # ((_x ^ _n)*(_x ^ _m)) <-- x^(m+n);

100  # ((x_IsNumber)^(n_IsInteger/(_m)))_(n>1) <-- MathIntPower(x,n)^(1/m);

100 # Sqrt(_n)^(m_IsEven) <-- n^(m/2);

100 # Abs(_a)^n_IsEven <-- a^n;
100 # Abs(_a)^n_IsOdd <-- Sign(a)*a^n;


200 # x_IsMatrix ^ n_IsPositiveInteger <-- x*(x^(n-1));
204 # (xlist_IsList ^ nlist_IsList)_(Length(xlist)=Length(nlist)) <--
	 Map("^",{xlist,nlist});
205 # (xlist_IsList ^ n_IsConstant)_(Not(IsList(n))) <--
	 Map({{xx},xx^n},{xlist});
206 # (_x ^ n_IsList)_(Not(IsList(x))) <-- Map({{xx},x^xx},{n});
249 # x_IsInfinity ^ 0 <-- Undefined;
250 # Infinity ^ (_n) <-- Infinity;
250 # Infinity ^ (_x_IsComplex) <-- Infinity;
250 # ((-Infinity) ^ (n_IsNumber))_(IsEven(n)) <-- Infinity;
250 # ((-Infinity) ^ (n_IsNumber))_(IsOdd(n)) <-- -Infinity;

250 # (x_IsNumber ^ Infinity)_(x> -1 And x < 1) <-- 0;
250 # (x_IsNumber ^ Infinity)_(x> 1) <-- Infinity;

// these Magnitude(x)s should probably be changed to Abs(x)s

250 # (x_IsComplex ^ Infinity)_(Magnitude(x) > 1) <-- Infinity;
250 # (x_IsComplex ^ Infinity)_(Magnitude(x) < -1) <-- -Infinity;
250 # (x_IsComplex ^ Infinity)_(Magnitude(x) > -1 And Magnitude(x) < 1) <-- 0;

250 # (x_IsNumber ^ -Infinity)_(x> -1 And x < 1) <-- Infinity;
250 # (x_IsNumber ^ -Infinity)_(x< -1) <-- 0;
250 # (x_IsNumber ^ -Infinity)_(x> 1) <-- 0;

255 # (x_IsComplex ^ Infinity)_(Abs(x) = 1) <-- Undefined;
255 # (x_IsComplex ^ -Infinity)_(Abs(x) = 1) <-- Undefined;



400 # _x ^ 0 <-- 1;

%/mathpiper


%mathpiper_docs,name="^",categories="Operators"
*CMD ^ --- arithmetic power
*STD
*CALL

	x^y
Precedence:
*EVAL PrecedenceGet("^")

*PARMS

{x} and {y} -- objects for which arithmetic operations are defined

*DESC

These are the basic arithmetic operations. They can work on integers,
rational numbers, complex numbers, vectors, matrices and lists.

These operators are implemented in the standard math library (as opposed
to being built-in). This means that they can be extended by the user.

*E.G.

In> 2^3
Result: 8;
%/mathpiper_docs