/***** Autogenerated from runpair.in; changes will be overwritten *****/

#line 1 "runtimebase.in"
/*****
 * runtimebase.in
 * Andy Hammerlindl  2009/07/28
 *
 * Common declarations needed for all code-generating .in files.
 *
 *****/


#line 1 "runpair.in"
/*****
 * runpair.in
 *
 * Runtime functions for pair operations.
 *
 *****/

#line 1 "runtimebase.in"
#include "stack.h"
#include "types.h"
#include "builtin.h"
#include "entry.h"
#include "errormsg.h"
#include "array.h"
#include "triple.h"
#include "callable.h"

using vm::stack;
using vm::error;
using vm::array;
using vm::callable;
using types::formal;
using types::function;
using camp::triple;

#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
#include <primitives.h>
#undef PRIMITIVE

typedef double real;

void unused(void *);

namespace run {
array *copyArray(array *a);
array *copyArray2(array *a);
array *copyArray3(array *a);

double *copyArrayC(const array *a, size_t dim=0, GCPlacement placement=NoGC);
double *copyArray2C(const array *a, bool square=true, size_t dim2=0,
                    GCPlacement placement=NoGC);

triple *copyTripleArrayC(const array *a, size_t dim=0);
triple *copyTripleArray2C(const array *a, bool square=true, size_t dim2=0);
double *copyTripleArray2Components(array *a, bool square=true, size_t dim2=0,
                                   GCPlacement placement=NoGC);
}

function *realRealFunction();

#define CURRENTPEN processData().currentpen

#line 10 "runpair.in"
#include "pair.h"

using namespace camp;

namespace run {
extern pair zero;
}

pair sin(pair z)
{
  return pair(sin(z.getx())*cosh(z.gety()),cos(z.getx())*sinh(z.gety())); 
}

pair exp(pair z) 
{ 
  return exp(z.getx())*expi(z.gety());
}

pair gamma(pair z)
{
  static double p[]={0.99999999999980993,676.5203681218851,-1259.1392167224028,
                     771.32342877765313,-176.61502916214059,12.507343278686905,
                     -0.13857109526572012,9.9843695780195716e-6,
                     1.5056327351493116e-7};
  static int n=sizeof(p)/sizeof(double);
  static double root2pi=sqrt(2*PI);
  if(z.getx() < 0.5)
    return PI/(sin(PI*z)*gamma(1.0-z));
  z -= 1.0;
  pair x=p[0];
  for(int i=1; i < n; ++i)
    x += p[i]/(z+i);
  pair t=n-1.5+z;
  return root2pi*pow(t,z+0.5)*exp(-t)*x;
}

// Autogenerated routines:



namespace run {
#line 49 "runpair.in"
void pairZero(stack *Stack)
{
#line 50 "runpair.in"
  {Stack->push<pair>(zero); return;}
}

#line 54 "runpair.in"
void realRealToPair(stack *Stack)
{
  real y=vm::pop<real>(Stack);
  real x=vm::pop<real>(Stack);
#line 55 "runpair.in"
  {Stack->push<pair>(pair(x,y)); return;}
}

#line 59 "runpair.in"
void pairNegate(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 60 "runpair.in"
  {Stack->push<pair>(-z); return;}
}

#line 64 "runpair.in"
// real xpart(pair z);
void pairXPart(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 65 "runpair.in"
  {Stack->push<real>(z.getx()); return;}
}

#line 69 "runpair.in"
// real ypart(pair z);
void pairYPart(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 70 "runpair.in"
  {Stack->push<real>(z.gety()); return;}
}

#line 74 "runpair.in"
// real length(pair z);
void gen_runpair5(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 75 "runpair.in"
  {Stack->push<real>(z.length()); return;}
}

#line 79 "runpair.in"
// real abs(pair z);
void gen_runpair6(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 80 "runpair.in"
  {Stack->push<real>(z.length()); return;}
}

#line 84 "runpair.in"
// pair sqrt(explicit pair z);
void gen_runpair7(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 85 "runpair.in"
  {Stack->push<pair>(Sqrt(z)); return;}
}

// Return the angle of z in radians.
#line 90 "runpair.in"
// real angle(pair z, bool warn=true);
void gen_runpair8(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  pair z=vm::pop<pair>(Stack);
#line 91 "runpair.in"
  if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
  {Stack->push<real>(z.angle()); return;}
}

// Return the angle of z in degrees in the interval [0,360).
#line 97 "runpair.in"
// real degrees(pair z, bool warn=true);
void gen_runpair9(stack *Stack)
{
  bool warn=vm::pop<bool>(Stack,true);
  pair z=vm::pop<pair>(Stack);
#line 98 "runpair.in"
  if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
  {Stack->push<real>(principalBranch(degrees(z.angle()))); return;}
}

// Convert degrees to radians.
#line 104 "runpair.in"
// real radians(real degrees);
void gen_runpair10(stack *Stack)
{
  real degrees=vm::pop<real>(Stack);
#line 105 "runpair.in"
  {Stack->push<real>(radians(degrees)); return;}
}

// Convert radians to degrees.
#line 110 "runpair.in"
// real degrees(real radians);
void gen_runpair11(stack *Stack)
{
  real radians=vm::pop<real>(Stack);
#line 111 "runpair.in"
  {Stack->push<real>(degrees(radians)); return;}
}

// Convert radians to degrees in [0,360).
#line 116 "runpair.in"
// real Degrees(real radians);
void gen_runpair12(stack *Stack)
{
  real radians=vm::pop<real>(Stack);
#line 117 "runpair.in"
  {Stack->push<real>(principalBranch(degrees(radians))); return;}
}

#line 121 "runpair.in"
// real Sin(real deg);
void gen_runpair13(stack *Stack)
{
  real deg=vm::pop<real>(Stack);
#line 122 "runpair.in"
  {Stack->push<real>(sin(radians(deg))); return;}
}

#line 126 "runpair.in"
// real Cos(real deg);
void gen_runpair14(stack *Stack)
{
  real deg=vm::pop<real>(Stack);
#line 127 "runpair.in"
  {Stack->push<real>(cos(radians(deg))); return;}
}

#line 131 "runpair.in"
// real Tan(real deg);
void gen_runpair15(stack *Stack)
{
  real deg=vm::pop<real>(Stack);
#line 132 "runpair.in"
  {Stack->push<real>(tan(radians(deg))); return;}
}

#line 136 "runpair.in"
// real aSin(real x);
void gen_runpair16(stack *Stack)
{
  real x=vm::pop<real>(Stack);
#line 137 "runpair.in"
  {Stack->push<real>(degrees(asin(x))); return;}
}

#line 141 "runpair.in"
// real aCos(real x);
void gen_runpair17(stack *Stack)
{
  real x=vm::pop<real>(Stack);
#line 142 "runpair.in"
  {Stack->push<real>(degrees(acos(x))); return;}
}

#line 146 "runpair.in"
// real aTan(real x);
void gen_runpair18(stack *Stack)
{
  real x=vm::pop<real>(Stack);
#line 147 "runpair.in"
  {Stack->push<real>(degrees(atan(x))); return;}
}

#line 151 "runpair.in"
// pair unit(pair z);
void gen_runpair19(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 152 "runpair.in"
  {Stack->push<pair>(unit(z)); return;}
}

#line 156 "runpair.in"
// pair dir(real degrees);
void gen_runpair20(stack *Stack)
{
  real degrees=vm::pop<real>(Stack);
#line 157 "runpair.in"
  {Stack->push<pair>(expi(radians(degrees))); return;}
}

#line 161 "runpair.in"
// pair dir(explicit pair z);
void gen_runpair21(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 162 "runpair.in"
  {Stack->push<pair>(unit(z)); return;}
}

#line 166 "runpair.in"
// pair expi(real angle);
void gen_runpair22(stack *Stack)
{
  real angle=vm::pop<real>(Stack);
#line 167 "runpair.in"
  {Stack->push<pair>(expi(angle)); return;}
}

#line 171 "runpair.in"
// pair exp(explicit pair z);
void gen_runpair23(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 172 "runpair.in" 
  {Stack->push<pair>(exp(z)); return;}
}

#line 176 "runpair.in"
// pair log(explicit pair z);
void gen_runpair24(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 177 "runpair.in" 
  {Stack->push<pair>(pair(log(z.length()),z.angle())); return;}
}

#line 181 "runpair.in"
// pair sin(explicit pair z);
void gen_runpair25(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 182 "runpair.in" 
  {Stack->push<pair>(sin(z)); return;}
}

#line 186 "runpair.in"
// pair cos(explicit pair z);
void gen_runpair26(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 187 "runpair.in" 
  {Stack->push<pair>(pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()))); return;} 
}

// Complex Gamma function
#line 192 "runpair.in"
// pair gamma(explicit pair z);
void gen_runpair27(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 193 "runpair.in"
  {Stack->push<pair>(gamma(z)); return;}
}

#line 197 "runpair.in"
// pair conj(pair z);
void gen_runpair28(stack *Stack)
{
  pair z=vm::pop<pair>(Stack);
#line 198 "runpair.in"
  {Stack->push<pair>(conj(z)); return;}
}

#line 202 "runpair.in"
// pair realmult(pair z, pair w);
void gen_runpair29(stack *Stack)
{
  pair w=vm::pop<pair>(Stack);
  pair z=vm::pop<pair>(Stack);
#line 203 "runpair.in"
  {Stack->push<pair>(pair (z.getx()*w.getx(),z.gety()*w.gety())); return;}
}

// To avoid confusion, a dot product requires explicit pair arguments.
#line 208 "runpair.in"
// real dot(explicit pair z, explicit pair w);
void gen_runpair30(stack *Stack)
{
  pair w=vm::pop<pair>(Stack);
  pair z=vm::pop<pair>(Stack);
#line 209 "runpair.in"
  {Stack->push<real>(dot(z,w)); return;}
}

#line 213 "runpair.in"
// pair bezier(pair a, pair b, pair c, pair d, real t);
void gen_runpair31(stack *Stack)
{
  real t=vm::pop<real>(Stack);
  pair d=vm::pop<pair>(Stack);
  pair c=vm::pop<pair>(Stack);
  pair b=vm::pop<pair>(Stack);
  pair a=vm::pop<pair>(Stack);
#line 214 "runpair.in"
  real onemt=1-t;
  real onemt2=onemt*onemt;
  {Stack->push<pair>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
}

#line 220 "runpair.in"
// pair bezierP(pair a, pair b, pair c, pair d, real t);
void gen_runpair32(stack *Stack)
{
  real t=vm::pop<real>(Stack);
  pair d=vm::pop<pair>(Stack);
  pair c=vm::pop<pair>(Stack);
  pair b=vm::pop<pair>(Stack);
  pair a=vm::pop<pair>(Stack);
#line 221 "runpair.in"
  {Stack->push<pair>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
}

#line 225 "runpair.in"
// pair bezierPP(pair a, pair b, pair c, pair d, real t);
void gen_runpair33(stack *Stack)
{
  real t=vm::pop<real>(Stack);
  pair d=vm::pop<pair>(Stack);
  pair c=vm::pop<pair>(Stack);
  pair b=vm::pop<pair>(Stack);
  pair a=vm::pop<pair>(Stack);
#line 226 "runpair.in"
  {Stack->push<pair>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
}

#line 230 "runpair.in"
// pair bezierPPP(pair a, pair b, pair c, pair d);
void gen_runpair34(stack *Stack)
{
  pair d=vm::pop<pair>(Stack);
  pair c=vm::pop<pair>(Stack);
  pair b=vm::pop<pair>(Stack);
  pair a=vm::pop<pair>(Stack);
#line 231 "runpair.in"
  {Stack->push<pair>(6.0*(d-a+3.0*(b-c))); return;}
}

} // namespace run

namespace trans {

void gen_runpair_venv(venv &ve)
{
#line 49 "runpair.in"
  REGISTER_BLTIN(run::pairZero,"pairZero");
#line 54 "runpair.in"
  REGISTER_BLTIN(run::realRealToPair,"realRealToPair");
#line 59 "runpair.in"
  REGISTER_BLTIN(run::pairNegate,"pairNegate");
#line 64 "runpair.in"
  addFunc(ve, run::pairXPart, primReal(), "xpart", formal(primPair(), "z", false, false));
#line 69 "runpair.in"
  addFunc(ve, run::pairYPart, primReal(), "ypart", formal(primPair(), "z", false, false));
#line 74 "runpair.in"
  addFunc(ve, run::gen_runpair5, primReal(), "length", formal(primPair(), "z", false, false));
#line 79 "runpair.in"
  addFunc(ve, run::gen_runpair6, primReal(), "abs", formal(primPair(), "z", false, false));
#line 84 "runpair.in"
  addFunc(ve, run::gen_runpair7, primPair(), "sqrt", formal(primPair(), "z", false, true));
#line 89 "runpair.in"
  addFunc(ve, run::gen_runpair8, primReal(), "angle", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
#line 96 "runpair.in"
  addFunc(ve, run::gen_runpair9, primReal(), "degrees", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
#line 103 "runpair.in"
  addFunc(ve, run::gen_runpair10, primReal(), "radians", formal(primReal(), "degrees", false, false));
#line 109 "runpair.in"
  addFunc(ve, run::gen_runpair11, primReal(), "degrees", formal(primReal(), "radians", false, false));
#line 115 "runpair.in"
  addFunc(ve, run::gen_runpair12, primReal(), "Degrees", formal(primReal(), "radians", false, false));
#line 121 "runpair.in"
  addFunc(ve, run::gen_runpair13, primReal(), "Sin", formal(primReal(), "deg", false, false));
#line 126 "runpair.in"
  addFunc(ve, run::gen_runpair14, primReal(), "Cos", formal(primReal(), "deg", false, false));
#line 131 "runpair.in"
  addFunc(ve, run::gen_runpair15, primReal(), "Tan", formal(primReal(), "deg", false, false));
#line 136 "runpair.in"
  addFunc(ve, run::gen_runpair16, primReal(), "aSin", formal(primReal(), "x", false, false));
#line 141 "runpair.in"
  addFunc(ve, run::gen_runpair17, primReal(), "aCos", formal(primReal(), "x", false, false));
#line 146 "runpair.in"
  addFunc(ve, run::gen_runpair18, primReal(), "aTan", formal(primReal(), "x", false, false));
#line 151 "runpair.in"
  addFunc(ve, run::gen_runpair19, primPair(), "unit", formal(primPair(), "z", false, false));
#line 156 "runpair.in"
  addFunc(ve, run::gen_runpair20, primPair(), "dir", formal(primReal(), "degrees", false, false));
#line 161 "runpair.in"
  addFunc(ve, run::gen_runpair21, primPair(), "dir", formal(primPair(), "z", false, true));
#line 166 "runpair.in"
  addFunc(ve, run::gen_runpair22, primPair(), "expi", formal(primReal(), "angle", false, false));
#line 171 "runpair.in"
  addFunc(ve, run::gen_runpair23, primPair(), "exp", formal(primPair(), "z", false, true));
#line 176 "runpair.in"
  addFunc(ve, run::gen_runpair24, primPair(), "log", formal(primPair(), "z", false, true));
#line 181 "runpair.in"
  addFunc(ve, run::gen_runpair25, primPair(), "sin", formal(primPair(), "z", false, true));
#line 186 "runpair.in"
  addFunc(ve, run::gen_runpair26, primPair(), "cos", formal(primPair(), "z", false, true));
#line 191 "runpair.in"
  addFunc(ve, run::gen_runpair27, primPair(), "gamma", formal(primPair(), "z", false, true));
#line 197 "runpair.in"
  addFunc(ve, run::gen_runpair28, primPair(), "conj", formal(primPair(), "z", false, false));
#line 202 "runpair.in"
  addFunc(ve, run::gen_runpair29, primPair(), "realmult", formal(primPair(), "z", false, false), formal(primPair(), "w", false, false));
#line 207 "runpair.in"
  addFunc(ve, run::gen_runpair30, primReal(), "dot", formal(primPair(), "z", false, true), formal(primPair(), "w", false, true));
#line 213 "runpair.in"
  addFunc(ve, run::gen_runpair31, primPair(), "bezier", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
#line 220 "runpair.in"
  addFunc(ve, run::gen_runpair32, primPair(), "bezierP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
#line 225 "runpair.in"
  addFunc(ve, run::gen_runpair33, primPair(), "bezierPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
#line 230 "runpair.in"
  addFunc(ve, run::gen_runpair34, primPair(), "bezierPPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
}

} // namespace trans
