Max 5 API Reference
00001 /* 00002 * jit.distance.minkovsky.c 00003 * 00004 * Copyright 2001-2005 - Cycling '74 00005 * Derek Gerstmann - derek@cycling74.com 00006 * 00007 * Functor for calculating Minkovsky distance 00008 * 00009 * Minkovsky distance uses an exponent control to 00010 * modulate the result between Manhattan [exp = 1] 00011 * and Euclidean [exp = 2] distances. 00012 */ 00013 00014 #include "jit.common.h" 00015 #include "jit.functor.h" 00016 00017 // -------------------------------------------------------------------------- 00018 00019 typedef struct _jit_functor_distance_minkovsky 00020 { 00021 t_jit_object ob; 00022 double exponent; // exponent control 00023 double invexponent; // inverse of exponent 00024 00025 } t_jit_functor_distance_minkovsky; 00026 00027 // -------------------------------------------------------------------------- 00028 00029 t_jit_object *jit_functor_distance_minkovsky_new(void); 00030 t_jit_err jit_functor_distance_minkovsky_free(t_jit_functor_distance_minkovsky *x); 00031 t_jit_err jit_functor_distance_minkovsky_exponent(t_jit_functor_distance_minkovsky *x, void *attr, long argc, t_atom *argv); 00032 t_jit_err jit_functor_distance_minkovsky_recalc(t_jit_functor_distance_minkovsky *x); 00033 00034 long jit_functor_distance_minkovsky_eval_fixed(t_jit_functor_distance_minkovsky *x, long dimcount, long *vals); 00035 float jit_functor_distance_minkovsky_eval_float32(t_jit_functor_distance_minkovsky *x, long dimcount, float *vals); 00036 double jit_functor_distance_minkovsky_eval_float64(t_jit_functor_distance_minkovsky *x, long dimcount, double *vals); 00037 00038 void jit_functor_distance_minkovsky_fixlut_init(void); 00039 00040 t_class *_jit_functor_distance_minkovsky_class; 00041 00042 // -------------------------------------------------------------------------- 00043 00044 t_jit_err jit_functor_distance_minkovsky_init(void) 00045 { 00046 t_jit_object *attr; 00047 00048 // create class 00049 _jit_functor_distance_minkovsky_class = jit_class_new("jit_functor_distance_minkovsky",(method)jit_functor_distance_minkovsky_new,(method)jit_functor_distance_minkovsky_free, 00050 sizeof(t_jit_functor_distance_minkovsky),0L); 00051 00052 // add attribute methods 00053 attr = jit_object_new(_jit_sym_jit_attr_offset,"exponent",_jit_sym_float64,0, 00054 (method)0L,(method)jit_functor_distance_minkovsky_exponent, 00055 calcoffset(t_jit_functor_distance_minkovsky,exponent)); 00056 jit_class_addattr(_jit_functor_distance_minkovsky_class,attr); 00057 00058 // add evaluation methods 00059 jit_class_addmethod(_jit_functor_distance_minkovsky_class, (method)jit_functor_distance_minkovsky_eval_fixed, "evalfixed", A_CANT, 0L); 00060 jit_class_addmethod(_jit_functor_distance_minkovsky_class, (method)jit_functor_distance_minkovsky_eval_float32, "evalfloat32", A_CANT, 0L); 00061 jit_class_addmethod(_jit_functor_distance_minkovsky_class, (method)jit_functor_distance_minkovsky_eval_float64, "evalfloat64", A_CANT, 0L); 00062 00063 // important to add last for subclassing methods 00064 jit_functor_setup_class(_jit_functor_distance_minkovsky_class,"distance","minkovsky"); 00065 jit_class_register(_jit_functor_distance_minkovsky_class); 00066 00067 return JIT_ERR_NONE; 00068 } 00069 00070 t_jit_object *jit_functor_distance_minkovsky_new(void) 00071 { 00072 long i; 00073 t_jit_functor_distance_minkovsky *x; 00074 00075 if (x = (t_jit_functor_distance_minkovsky *)jit_object_alloc(_jit_functor_distance_minkovsky_class)) { 00076 00077 // initialization 00078 x->exponent = 0.5; 00079 jit_functor_distance_minkovsky_recalc(x); 00080 } 00081 00082 return (t_jit_object *)x; 00083 } 00084 00085 t_jit_err jit_functor_distance_minkovsky_free(t_jit_functor_distance_minkovsky *x) 00086 { 00087 return JIT_ERR_NONE; 00088 } 00089 00090 t_jit_err jit_functor_distance_minkovsky_exponent(t_jit_functor_distance_minkovsky *x, void *attr, long argc, t_atom *argv) 00091 { 00092 double v; 00093 00094 if (x) { 00095 v = jit_atom_getfloat(argv); 00096 if(x->exponent != v) { 00097 x->exponent = v; 00098 jit_functor_distance_minkovsky_recalc(x); 00099 } 00100 return JIT_ERR_NONE; 00101 } 00102 return JIT_ERR_INVALID_PTR; 00103 } 00104 00105 t_jit_err jit_functor_distance_minkovsky_recalc(t_jit_functor_distance_minkovsky *x) 00106 { 00107 // calculate intermediary values for efficiency 00108 x->invexponent = 1.0 / x->exponent; 00109 return JIT_ERR_NONE; 00110 } 00111 00112 // -------------------------------------------------------------------------- 00113 00114 long jit_functor_distance_minkovsky_eval_fixed(t_jit_functor_distance_minkovsky *x, long dimcount, long *vals) 00115 { 00116 return jit_functor_eval_fixed_with_float64((t_jit_object *)x,dimcount,vals, 00117 (t_jit_functor_float64_sig)jit_functor_distance_minkovsky_eval_float64); 00118 } 00119 00120 float jit_functor_distance_minkovsky_eval_float32(t_jit_functor_distance_minkovsky *x, long dimcount, float *vals) 00121 { 00122 return jit_functor_eval_float32_with_float64((t_jit_object *)x,dimcount,vals, 00123 (t_jit_functor_float64_sig)jit_functor_distance_minkovsky_eval_float64); 00124 } 00125 00126 double jit_functor_distance_minkovsky_eval_float64(t_jit_functor_distance_minkovsky *x, long dimcount, double *vals) 00127 { 00128 long i; 00129 double rval = 0; 00130 00131 // special cases for improved performance 00132 if(x->exponent == 0.5) 00133 { 00134 for (i=0;i<dimcount;i++) { 00135 rval += jit_math_sqrt(JIT_MATH_F64_ABS(vals[i])); 00136 } 00137 return JIT_MATH_SQR(rval); 00138 } 00139 else if(x->exponent == 4.0) 00140 { 00141 for (i=0;i<dimcount;i++) { 00142 rval += JIT_MATH_SQR(vals[i]); 00143 } 00144 return jit_math_sqrt(jit_math_sqrt(rval)); 00145 } 00146 else 00147 { 00148 for (i=0;i<dimcount;i++) { 00149 rval += jit_math_pow(JIT_MATH_F64_ABS(vals[i]), x->exponent); 00150 } 00151 return jit_math_pow(rval, x->invexponent); 00152 } 00153 00154 return rval; 00155 } 00156 00157 // --------------------------------------------------------------------------
Copyright © 2008, Cycling '74