lms-video/pd-0.44-2/extra/expr~/vexp_fun.c
Santi Noreña e85d191b46 - Reestructuración de ficheros y directorios general
- merge v0.01 --> Añadido fileselector
- Añadidas fuentes de Gem y Pure Data
- pix2jpg incluído en Gem. Archivos de construcción de Gem modificados.
- Añadido fichero ompiling.txt con instrucciones de compilación
2013-02-04 18:00:17 +01:00

1315 lines
51 KiB
C

/*
* jMax
* Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* See file LICENSE for further informations on licensing terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Based on Max/ISPW by Miller Puckette.
*
* Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell.
*
*/
/* "expr" was written by Shahrokh Yadegari c. 1989. -msp
*
* Nov. 2001 --sdy
* conversion for expr~
*
* Jan, 2002 --sdy
* added fmod()
*
* May 2002
* added floor and ceil for expr -- Orm Finnendahl
*
* July 2002 --sdy
* added the following math funtions:
* cbrt - cube root
* erf - error function
* erfc - complementary error function
* expm1 - exponential minus 1,
* log1p - logarithm of 1 plus
* isinf - is the value infinite,
* finite - is the value finite
* isnan -- is the resut a nan (Not a number)
* copysign - copy sign of a number
* ldexp - multiply floating-point number by integral power of 2
* imodf - get signed integral value from floating-point number
* modf - get signed fractional value from floating-point number
* drem - floating-point remainder function
*
* The following are done but not popular enough in math libss
* to be included yet
* hypoth - Euclidean distance function
* trunc
* round
* nearbyint -
*/
/*
* vexp_func.c -- this file include all the functions for vexp.
* the first two arguments to the function are the number
* of argument and an array of arguments (argc, argv)
* the last argument is a pointer to a struct ex_ex for
* the result. Up do this point, the content of the
* struct ex_ex that these functions receive are either
* ET_INT (long), ET_FLT (t_float), or ET_SYM (char **, it is
* char ** and not char * since NewHandle of Mac returns
* a char ** for relocatability.) The common practice in
* these functions is that they figure out the type of their
* result according to the type of the arguments. In general
* the ET_SYM is used an ET_INT when we expect a value.
* It is the users responsibility not to pass strings to the
* function.
*/
#include <stdlib.h>
#include <string.h>
#define __STRICT_BSD__
#include <math.h>
#undef __STRICT_BSD__
#include "vexp.h"
/* forward declarations */
static void ex_min(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_max(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_toint(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_rint(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_tofloat(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_pow(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_exp(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_log(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_ln(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_sin(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_cos(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_asin(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_acos(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_tan(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_atan(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_sinh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_cosh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_asinh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_acosh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_tanh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_atanh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_atan2(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_sqrt(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_fact(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_random(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_abs(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_fmod(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_ceil(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_floor(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_if(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_ldexp(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_imodf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_modf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
#ifndef _WIN32
static void ex_cbrt(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_erf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_erfc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_expm1(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_log1p(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_isinf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_finite(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_isnan(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_copysign(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_drem(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
#endif
#ifdef notdef
/* the following will be added once they are more popular in math libraries */
static void ex_round(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_trunc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_nearbyint(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
static void ex_hypoth(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
#endif
t_ex_func ex_funcs[] = {
{"min", ex_min, 2},
{"max", ex_max, 2},
{"int", ex_toint, 1},
{"rint", ex_rint, 1},
{"float", ex_tofloat, 1},
{"fmod", ex_fmod, 2},
{"floor", ex_floor, 2},
{"ceil", ex_ceil, 2},
{"pow", ex_pow, 2},
{"sqrt", ex_sqrt, 1},
{"exp", ex_exp, 1},
{"log10", ex_log, 1},
{"ln", ex_ln, 1},
{"log", ex_ln, 1},
{"sin", ex_sin, 1},
{"cos", ex_cos, 1},
{"tan", ex_tan, 1},
{"asin", ex_asin, 1},
{"acos", ex_acos, 1},
{"atan", ex_atan, 1},
{"atan2", ex_atan2, 2},
{"sinh", ex_sinh, 1},
{"cosh", ex_cosh, 1},
{"tanh", ex_tanh, 1},
{"fact", ex_fact, 1},
{"random", ex_random, 2}, /* random number */
{"abs", ex_abs, 1},
{"if", ex_if, 3},
{"ldexp ", ex_ldexp, 1},
{"imodf ", ex_imodf, 1},
{"modf", ex_modf, 1},
#ifndef _WIN32
{"cbrt", ex_cbrt, 1},
{"erf", ex_erf, 1},
{"erfc", ex_erfc, 1},
{"expm1", ex_expm1, 1},
{"log1p", ex_log1p, 1},
{"isinf", ex_isinf, 1},
{"finite", ex_finite, 1},
{"isnan", ex_isnan, 1},
{"copysig", ex_copysign, 1},
{"drem", ex_drem, 1},
{"asinh", ex_asinh, 1},
{"acosh", ex_acosh, 1},
{"atanh", ex_atanh, 1}, /* hyperbolic atan */
#endif
#ifdef PD
{"size", ex_size, 1},
{"sum", ex_sum, 1},
{"Sum", ex_Sum, 3},
{"avg", ex_avg, 1},
{"Avg", ex_Avg, 3},
{"store", ex_store, 3},
#endif
#ifdef notdef
/* the following will be added once they are more popular in math libraries */
{"round", ex_round, 1},
{"trunc", ex_trunc, 1},
{"nearbyint", ex_nearbyint, 1},
{"hypoth", ex_hypoth, 1},
#endif
{0, 0, 0}
};
/*
* FUN_EVAL -- do type checking, evaluate a function,
* if fltret is set return float
* otherwise return value based on regular typechecking,
*/
#define FUNC_EVAL(left, right, func, leftfuncast, rightfuncast, optr, fltret) \
switch (left->ex_type) { \
case ET_INT: \
switch(right->ex_type) { \
case ET_INT: \
if (optr->ex_type == ET_VEC) { \
op = optr->ex_vec; \
scalar = (t_float)func(leftfuncast left->ex_int, \
rightfuncast right->ex_int); \
j = e->exp_vsize; \
while (j--) \
*op++ = scalar; \
} else { \
if (fltret) { \
optr->ex_type = ET_FLT; \
optr->ex_flt = (t_float)func(leftfuncast \
left->ex_int, rightfuncast right->ex_int); \
} else { \
optr->ex_type = ET_INT; \
optr->ex_int = (int)func(leftfuncast \
left->ex_int, rightfuncast right->ex_int); \
} \
} \
break; \
case ET_FLT: \
if (optr->ex_type == ET_VEC) { \
op = optr->ex_vec; \
scalar = (t_float)func(leftfuncast left->ex_int, \
rightfuncast right->ex_flt); \
j = e->exp_vsize; \
while (j--) \
*op++ = scalar; \
} else { \
optr->ex_type = ET_FLT; \
optr->ex_flt = (t_float)func(leftfuncast left->ex_int, \
rightfuncast right->ex_flt); \
} \
break; \
case ET_VEC: \
case ET_VI: \
if (optr->ex_type != ET_VEC) { \
if (optr->ex_type == ET_VI) { \
post("expr~: Int. error %d", __LINE__); \
abort(); \
} \
optr->ex_type = ET_VEC; \
optr->ex_vec = (t_float *) \
fts_malloc(sizeof (t_float)*e->exp_vsize); \
} \
scalar = left->ex_int; \
rp = right->ex_vec; \
op = optr->ex_vec; \
j = e->exp_vsize; \
while (j--) { \
*op++ = (t_float)func(leftfuncast scalar, \
rightfuncast *rp); \
rp++; \
} \
break; \
case ET_SYM: \
default: \
post_error((fts_object_t *) e, \
"expr: FUNC_EVAL(%d): bad right type %ld\n", \
__LINE__, right->ex_type);\
} \
break; \
case ET_FLT: \
switch(right->ex_type) { \
case ET_INT: \
if (optr->ex_type == ET_VEC) { \
op = optr->ex_vec; \
scalar = (t_float)func(leftfuncast left->ex_flt, \
rightfuncast right->ex_int); \
j = e->exp_vsize; \
while (j--) \
*op++ = scalar; \
} else { \
optr->ex_type = ET_FLT; \
optr->ex_flt = (t_float)func(leftfuncast left->ex_flt, \
rightfuncast right->ex_int); \
} \
break; \
case ET_FLT: \
if (optr->ex_type == ET_VEC) { \
op = optr->ex_vec; \
scalar = (t_float)func(leftfuncast left->ex_flt, \
rightfuncast right->ex_flt); \
j = e->exp_vsize; \
while (j--) \
*op++ = scalar; \
} else { \
optr->ex_type = ET_FLT; \
optr->ex_flt = (t_float)func(leftfuncast left->ex_flt, \
rightfuncast right->ex_flt); \
} \
break; \
case ET_VEC: \
case ET_VI: \
if (optr->ex_type != ET_VEC) { \
if (optr->ex_type == ET_VI) { \
post("expr~: Int. error %d", __LINE__); \
abort(); \
} \
optr->ex_type = ET_VEC; \
optr->ex_vec = (t_float *) \
fts_malloc(sizeof (t_float) * e->exp_vsize);\
} \
scalar = left->ex_flt; \
rp = right->ex_vec; \
op = optr->ex_vec; \
j = e->exp_vsize; \
while (j--) { \
*op++ = (t_float)func(leftfuncast scalar, \
rightfuncast *rp); \
rp++; \
} \
break; \
case ET_SYM: \
default: \
post_error((fts_object_t *) e, \
"expr: FUNC_EVAL(%d): bad right type %ld\n", \
__LINE__, right->ex_type);\
} \
break; \
case ET_VEC: \
case ET_VI: \
if (optr->ex_type != ET_VEC) { \
if (optr->ex_type == ET_VI) { \
post("expr~: Int. error %d", __LINE__); \
abort(); \
} \
optr->ex_type = ET_VEC; \
optr->ex_vec = (t_float *) \
fts_malloc(sizeof (t_float) * e->exp_vsize); \
} \
op = optr->ex_vec; \
lp = left->ex_vec; \
switch(right->ex_type) { \
case ET_INT: \
scalar = right->ex_int; \
j = e->exp_vsize; \
while (j--) { \
*op++ = (t_float)func(leftfuncast *lp, \
rightfuncast scalar); \
lp++; \
} \
break; \
case ET_FLT: \
scalar = right->ex_flt; \
j = e->exp_vsize; \
while (j--) { \
*op++ = (t_float)func(leftfuncast *lp, \
rightfuncast scalar); \
lp++; \
} \
break; \
case ET_VEC: \
case ET_VI: \
rp = right->ex_vec; \
j = e->exp_vsize; \
while (j--) { \
/* \
* on a RISC processor one could copy \
* 8 times in each round to get a considerable \
* improvement \
*/ \
*op++ = (t_float)func(leftfuncast *lp, \
rightfuncast *rp); \
rp++; lp++; \
} \
break; \
case ET_SYM: \
default: \
post_error((fts_object_t *) e, \
"expr: FUNC_EVAL(%d): bad right type %ld\n", \
__LINE__, right->ex_type);\
} \
break; \
case ET_SYM: \
default: \
post_error((fts_object_t *) e, \
"expr: FUNC_EVAL(%d): bad left type %ld\n", \
__LINE__, left->ex_type); \
}
/*
* FUNC_EVAL_UNARY - evaluate a unary function,
* if fltret is set return t_float
* otherwise return value based on regular typechecking,
*/
#define FUNC_EVAL_UNARY(left, func, leftcast, optr, fltret) \
switch(left->ex_type) { \
case ET_INT: \
if (optr->ex_type == ET_VEC) { \
ex_mkvector(optr->ex_vec, \
(t_float)(func (leftcast left->ex_int)), e->exp_vsize);\
break; \
} \
if (fltret) { \
optr->ex_type = ET_FLT; \
optr->ex_flt = (t_float) func(leftcast left->ex_int); \
break; \
} \
optr->ex_type = ET_INT; \
optr->ex_int = (int) func(leftcast left->ex_int); \
break; \
case ET_FLT: \
if (optr->ex_type == ET_VEC) { \
ex_mkvector(optr->ex_vec, \
(t_float)(func (leftcast left->ex_flt)), e->exp_vsize);\
break; \
} \
optr->ex_type = ET_FLT; \
optr->ex_flt = (t_float) func(leftcast left->ex_flt); \
break; \
case ET_VI: \
case ET_VEC: \
if (optr->ex_type != ET_VEC) { \
optr->ex_type = ET_VEC; \
optr->ex_vec = (t_float *) \
fts_malloc(sizeof (t_float)*e->exp_vsize); \
} \
op = optr->ex_vec; \
lp = left->ex_vec; \
j = e->exp_vsize; \
while (j--) \
*op++ = (t_float)(func (leftcast *lp++)); \
break; \
default: \
post_error((fts_object_t *) e, \
"expr: FUNV_EVAL_UNARY(%d): bad left type %ld\n",\
__LINE__, left->ex_type); \
}
#undef min
#undef max
#define min(x,y) (x > y ? y : x)
#define max(x,y) (x > y ? x : y)
#define FUNC_DEF(ex_func, func, castleft, castright, fltret); \
static void \
ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\
{ \
struct ex_ex *left, *right; \
t_float *op; /* output pointer */ \
t_float *lp, *rp; /* left and right vector pointers */ \
t_float scalar; \
int j; \
\
left = argv++; \
right = argv; \
FUNC_EVAL(left, right, func, castleft, castright, optr, fltret); \
}
#define FUNC_DEF_UNARY(ex_func, func, cast, fltret); \
static void \
ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\
{ \
struct ex_ex *left; \
t_float *op; /* output pointer */ \
t_float *lp, *rp; /* left and right vector pointers */ \
t_float scalar; \
int j; \
\
left = argv++; \
\
FUNC_EVAL_UNARY(left, func, cast, optr, fltret); \
}
/*
* ex_min -- if any of the arguments are or the output are vectors, a vector
* of floats is generated otherwise the type of the result is the
* type of the smaller value
*/
static void
ex_min(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
right = argv;
FUNC_EVAL(left, right, min, (double), (double), optr, 0);
}
/*
* ex_max -- if any of the arguments are or the output are vectors, a vector
* of floats is generated otherwise the type of the result is the
* type of the larger value
*/
static void
ex_max(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
right = argv;
FUNC_EVAL(left, right, max, (double), (double), optr, 0);
}
/*
* ex_toint -- convert to integer
*/
static void
ex_toint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
#define toint(x) ((int)(x))
FUNC_EVAL_UNARY(left, toint, (int), optr, 0);
}
#ifdef _WIN32
/* No rint in NT land ??? */
double rint(double x);
double
rint(double x)
{
return (floor(x + 0.5));
}
#endif
/*
* ex_rint -- rint() round to the nearest int according to the common
* rounding mechanism
*/
static void
ex_rint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, rint, (double), optr, 1);
}
/*
* ex_tofloat -- convert to t_float
*/
static void
ex_tofloat(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
#define tofloat(x) ((t_float)(x))
FUNC_EVAL_UNARY(left, tofloat, (int), optr, 1);
}
/*
* ex_pow -- the power of
*/
static void
ex_pow(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
right = argv;
FUNC_EVAL(left, right, pow, (double), (double), optr, 1);
}
/*
* ex_sqrt -- square root
*/
static void
ex_sqrt(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, sqrt, (double), optr, 1);
}
/*
* ex_exp -- e to the power of
*/
static void
ex_exp(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, exp, (double), optr, 1);
}
/*
* ex_log -- 10 based logarithm
*/
static void
ex_log(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, log10, (double), optr, 1);
}
/*
* ex_ln -- natural log
*/
static void
ex_ln(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, log, (double), optr, 1);
}
static void
ex_sin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, sin, (double), optr, 1);
}
static void
ex_cos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, cos, (double), optr, 1);
}
static void
ex_tan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, tan, (double), optr, 1);
}
static void
ex_asin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, asin, (double), optr, 1);
}
static void
ex_acos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, acos, (double), optr, 1);
}
static void
ex_atan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, atan, (double), optr, 1);
}
/*
*ex_atan2 --
*/
static void
ex_atan2(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
right = argv;
FUNC_EVAL(left, right, atan2, (double), (double), optr, 1);
}
/*
* ex_fmod -- floating point modulo
*/
static void
ex_fmod(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
right = argv;
FUNC_EVAL(left, right, fmod, (double), (double), optr, 1);
}
/*
* ex_floor -- floor
*/
static void
ex_floor(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, floor, (double), optr, 1);
}
/*
* ex_ceil -- ceil
*/
static void
ex_ceil(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, ceil, (double), optr, 1);
}
static void
ex_sinh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, sinh, (double), optr, 1);
}
static void
ex_cosh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, cosh, (double), optr, 1);
}
static void
ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, tanh, (double), optr, 1);
}
#ifndef _WIN32
static void
ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, asinh, (double), optr, 1);
}
static void
ex_acosh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, acosh, (double), optr, 1);
}
static void
ex_atanh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, atanh, (double), optr, 1);
}
#endif
static int
ex_dofact(int i)
{
int ret = 0;
if (i)
ret = 1;
else
return (0);
do {
ret *= i;
} while (--i);
return(ret);
}
static void
ex_fact(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, ex_dofact, (int), optr, 0);
}
static int
ex_dorandom(int i1, int i2)
{
return(i1 + (((i2 - i1) * (rand() & 0x7fffL)) >> 15));
}
/*
* ex_random -- return a random number
*/
static void
ex_random(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
right = argv;
FUNC_EVAL(left, right, ex_dorandom, (int), (int), optr, 0);
}
static void
ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float scalar;
int j;
left = argv++;
FUNC_EVAL_UNARY(left, fabs, (double), optr, 0);
}
/*
*ex_if -- floating point modulo
*/
static void
ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
{
struct ex_ex *left, *right, *cond, *res;
t_float *op; /* output pointer */
t_float *lp, *rp; /* left and right vector pointers */
t_float *cp; /* condition pointer */
t_float leftvalue, rightvalue;
int j;
cond = argv++;
left = argv++;
right = argv;
switch (cond->ex_type) {
case ET_VEC:
case ET_VI:
if (optr->ex_type != ET_VEC) {
if (optr->ex_type == ET_VI) {
/* SDY remove this test */
post("expr~: Int. error %d", __LINE__);
return;
}
optr->ex_type = ET_VEC;
optr->ex_vec = (t_float *)
fts_malloc(sizeof (t_float) * e->exp_vsize);
}
op = optr->ex_vec;
j = e->exp_vsize;
cp = cond->ex_vec;
switch (left->ex_type) {
case ET_INT:
leftvalue = left->ex_int;
switch (right->ex_type) {
case ET_INT:
rightvalue = right->ex_int;
while (j--) {
if (*cp++)
*op++ = leftvalue;
else
*op++ = rightvalue;
}
return;
case ET_FLT:
rightvalue = right->ex_flt;
while (j--) {
if (*cp++)
*op++ = leftvalue;
else
*op++ = rightvalue;
}
return;
case ET_VEC:
case ET_VI:
rp = right->ex_vec;
while (j--) {
if (*cp++)
*op++ = leftvalue;
else
*op++ = *rp;
rp++;
}
return;
case ET_SYM:
default:
post_error((fts_object_t *) e,
"expr: FUNC_EVAL(%d): bad right type %ld\n",
__LINE__, right->ex_type);
return;
}
case ET_FLT:
leftvalue = left->ex_flt;
switch (right->ex_type) {
case ET_INT:
rightvalue = right->ex_int;
while (j--) {
if (*cp++)
*op++ = leftvalue;
else
*op++ = rightvalue;
}
return;
case ET_FLT:
rightvalue = right->ex_flt;
while (j--) {
if (*cp++)
*op++ = leftvalue;
else
*op++ = rightvalue;
}
return;
case ET_VEC:
case ET_VI:
rp = right->ex_vec;
while (j--) {
if (*cp++)
*op++ = leftvalue;
else
*op++ = *rp;
rp++;
}
return;
case ET_SYM:
default:
post_error((fts_object_t *) e,
"expr: FUNC_EVAL(%d): bad right type %ld\n",
__LINE__, right->ex_type);
return;
}
case ET_VEC:
case ET_VI:
lp = left->ex_vec;
switch (right->ex_type) {
case ET_INT:
rightvalue = right->ex_int;
while (j--) {
if (*cp++)
*op++ = *lp;
else
*op++ = rightvalue;
lp++;
}
return;
case ET_FLT:
rightvalue = right->ex_flt;
while (j--) {
if (*cp++)
*op++ = *lp;
else
*op++ = rightvalue;
lp++;
}
return;
case ET_VEC:
case ET_VI:
rp = right->ex_vec;
while (j--) {
if (*cp++)
*op++ = *lp;
else
*op++ = *rp;
lp++; rp++;
}
return;
case ET_SYM:
default:
post_error((fts_object_t *) e,
"expr: FUNC_EVAL(%d): bad right type %ld\n",
__LINE__, right->ex_type);
return;
}
case ET_SYM:
default:
post_error((fts_object_t *) e,
"expr: FUNC_EVAL(%d): bad left type %ld\n",
__LINE__, left->ex_type);
return;
}
case ET_INT:
if (cond->ex_int)
res = left;
else
res = right;
break;
case ET_FLT:
if (cond->ex_flt)
res = left;
else
res = right;
break;
case ET_SYM:
default:
post_error((fts_object_t *) e,
"expr: FUNC_EVAL(%d): bad condition type %ld\n",
__LINE__, cond->ex_type);
return;
}
switch(res->ex_type) {
case ET_INT:
if (optr->ex_type == ET_VEC) {
ex_mkvector(optr->ex_vec, (t_float)res->ex_int,
e->exp_vsize);
return;
}
*optr = *res;
return;
case ET_FLT:
if (optr->ex_type == ET_VEC) {
ex_mkvector(optr->ex_vec, (t_float)res->ex_flt,
e->exp_vsize);
return;
}
*optr = *res;
return;
case ET_VEC:
case ET_VI:
if (optr->ex_type != ET_VEC) {
if (optr->ex_type == ET_VI) {
/* SDY remove this test */
post("expr~: Int. error %d", __LINE__);
return;
}
optr->ex_type = ET_VEC;
optr->ex_vec = (t_float *)
fts_malloc(sizeof (t_float) * e->exp_vsize);
}
memcpy(optr->ex_vec, res->ex_vec, e->exp_vsize*sizeof(t_float));
return;
case ET_SYM:
default:
post_error((fts_object_t *) e,
"expr: FUNC_EVAL(%d): bad res type %ld\n",
__LINE__, res->ex_type);
return;
}
}
/*
* ex_imodf - extract signed integral value from floating-point number
*/
static double
imodf(double x)
{
double xx;
modf(x, &xx);
return (xx);
}
FUNC_DEF_UNARY(ex_imodf, imodf, (double), 1);
/*
* ex_modf - extract signed fractional value from floating-point number
*
* using fracmodf because fmodf() is alrady defined in a .h file
*/
static double
fracmodf(double x)
{
double xx;
return(modf(x, &xx));
}
FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1);
/*
* ex_ldexp - multiply floating-point number by integral power of 2
*/
FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1);
#ifndef _WIN32
/*
* ex_cbrt - cube root
*/
FUNC_DEF_UNARY(ex_cbrt, cbrt, (double), 1);
/*
* ex_erf - error function
*/
FUNC_DEF_UNARY(ex_erf, erf, (double), 1);
/*
* ex_erfc - complementary error function
*/
FUNC_DEF_UNARY(ex_erfc, erfc, (double), 1);
/*
* ex_expm1 - exponential minus 1,
*/
FUNC_DEF_UNARY(ex_expm1, expm1, (double), 1);
/*
* ex_log1p - logarithm of 1 plus
*/
FUNC_DEF_UNARY(ex_log1p, log1p, (double), 1);
/*
* ex_isinf - is the value infinite,
*/
FUNC_DEF_UNARY(ex_isinf, isinf, (double), 0);
/*
* ex_finite - is the value finite
*/
FUNC_DEF_UNARY(ex_finite, isfinite, (double), 0);
/*
* ex_isnan -- is the resut a nan (Not a number)
*/
FUNC_DEF_UNARY(ex_isnan, isnan, (double), 0);
/*
* ex_copysign - copy sign of a number
*/
FUNC_DEF(ex_copysign, copysign, (double), (double), 1);
/*
* ex_drem - floating-point remainder function
*/
FUNC_DEF(ex_drem, remainder, (double), (double), 1);
#endif
#ifdef notdef
/* the following will be added once they are more popular in math libraries */
/*
* ex_hypoth - Euclidean distance function
*/
FUNC_DEF(ex_hypoth, hypoth, (double), (double), 1);
/*
* ex_round - round to nearest integer, away from zero
*/
FUNC_DEF_UNARY(ex_round, round, (double), 1);
/*
* ex_trunc - round to interger, towards zero
*/
FUNC_DEF_UNARY(ex_trunc, trunc, (double), 1);
/*
* ex_nearbyint - round to nearest integer
*/
FUNC_DEF_UNARY(ex_nearbyint, nearbyint, (double), 1);
#endif