📄 cmutil.c
字号:
} } else { if (out > threshold_upper) { /* Limit Out @ Upper Bound */ pout_pcntl_lower= 0.0; if (out < (out_upper_limit+limit_range)) { /* Parabolic */ cm_smooth_corner(out,out_upper_limit,out_upper_limit, limit_range,1.0,0.0,&limited_out, &pout_pin); pout_pin = gain * pout_pin; cm_smooth_discontinuity(out,threshold_upper,0.0,out_upper_limit, 1.0,&pout_pcntl_upper,&junk); } else { /* Hard-Limited Region */ limited_out = out_upper_limit; pout_pin = 0.0; pout_pcntl_upper = 1.0; } } else { /* No Limiting Needed */ limited_out = out; pout_pin = gain; pout_pcntl_lower = 0.0; pout_pcntl_upper = 0.0; } } *out_final = limited_out; *pout_pin_final = pout_pin; *pout_pcntl_lower_final = pout_pcntl_lower; *pout_pcntl_upper_final = pout_pcntl_upper;} /**** End Controlled Limiter Function ****/ /*=============================================================================*//* Piecewise Linear Smoothing Function ********************** The following is a transfer curve function which ** accepts as input an "x" value, and returns a "y" ** value. The transfer characteristic is a smoothed ** piece-wise linear curve described by *x and *y array ** coordinate pairs. ** ** Created 8/14/91 ** Last Modified 8/14/91 J.P.Murray ************************************************************//************************************************************ ** ^ x[4] ** x[1] | * ** | midpoint /|\ ** | | / \ ** | V | / | \ ** *----*----* \ ** midpoint /| | | \ ** | / || * <- midpoint ** V/ | |x[3] \ ** <-----------*------------O------------\-------------> ** | / | \ | | ** / | \ ** |/ | \| | ** * | *-----*---> ** /| | x[5] x[6] ** / | ** / x[0] | ** / | ** / | ** / | ** V ** ************************************************************//************************************************************ ** Note that for the cm_smooth_pwl function, the arguments ** are as listed below: ** ** ** double x_input; input * ** double *x; pointer to the x-coordinate ** array * ** double *y; pointer to the y-coordinate ** array * ** int size; size of the arrays ** ** double input_domain; smoothing range * ** double dout_din; partial derivative of the ** output w.r.t. the input * ** ************************************************************/double cm_smooth_pwl(double x_input, double *x, double *y, int size, double input_domain, double *dout_din) { int i; /* generic loop counter index */ double lower_seg; /* x segment below which input resides */ double upper_seg; /* x segment above which the input resides */ double lower_slope; /* slope of the lower segment */ double upper_slope; /* slope of the upper segment */ double out; /* output */ double threshold_lower; /* value below which the output begins smoothing */ double threshold_upper; /* value above which the output begins smoothing */ /* char *limit_error="\n***ERROR***\nViolation of 50% rule in breakpoints!\n";*/ /* Determine segment boundaries within which x_input resides */ if (x_input <= (*(x+1) + *x)/2.0) {/*** x_input below lowest midpoint ***/ *dout_din = (*(y+1) - *y)/(*(x+1) - *x); out = *y + (x_input - *x) * *dout_din; } else { if (x_input >= (*(x+size-2) + *(x+size-1))/2.0) { /*** x_input above highest midpoint ***/ *dout_din = (*(y+size-1) - *(y+size-2)) / (*(x+size-1) - *(x+size-2)); out = *(y+size-1) + (x_input - *(x+size-1)) * *dout_din; } else { /*** x_input within bounds of end midpoints... ***/ /*** must determine position progressively & then ***/ /*** calculate required output. ***/ for (i=1; i<size; i++) { if (x_input < (*(x+i) + *(x+i+1))/2.0) { /* approximate position known... */ lower_seg = (*(x+i) - *(x+i-1)); upper_seg = (*(x+i+1) - *(x+i)); /* Calculate input_domain about this region's breakpoint.*/ /* Translate input_domain into an absolute.... */ if ( lower_seg <= upper_seg ) /* Use lower */ /* segment */ /* for % calc.*/ input_domain = input_domain * lower_seg; else /* Use upper */ /* segment */ /* for % calc.*/ input_domain = input_domain * upper_seg; /* Set up threshold values about breakpoint... */ threshold_lower = *(x+i) - input_domain; threshold_upper = *(x+i) + input_domain; /* Determine where x_input is within region & determine */ /* output and partial values.... */ if (x_input < threshold_lower) { /* Lower linear region */ *dout_din = (*(y+i) - *(y+i-1))/lower_seg; out = *(y+i) + (x_input - *(x+i)) * *dout_din; } else { if (x_input < threshold_upper) { /* Parabolic region */ lower_slope = (*(y+i) - *(y+i-1))/lower_seg; upper_slope = (*(y+i+1) - *(y+i))/upper_seg; cm_smooth_corner(x_input,*(x+i),*(y+i),input_domain, lower_slope,upper_slope,&out,dout_din); } else { /* Upper linear region */ *dout_din = (*(y+i+1) - *(y+i))/upper_seg; out = *(y+i) + (x_input - *(x+i)) * *dout_din; } } break; /* Break search loop...x_input has been found, */ /* and out and *dout_din have been assigned. */ } } } } return out;} Complex_t cm_complex_set(double real, double imag){ /* Create a complex number with the real and imaginary */ /* parts specified in the argument list, and return it */ Complex_t c; c.real = real; c.imag = imag; return(c);}Complex_t cm_complex_add(Complex_t x, Complex_t y){ /* Add the two complex numbers and return the result */ Complex_t c; c.real = x.real + y.real; c.imag = x.imag + y.imag; return(c);}Complex_t cm_complex_subtract(Complex_t x, Complex_t y){ /* Subtract the second arg from the first and return the result */ Complex_t c; c.real = x.real - y.real; c.imag = x.imag - y.imag; return(c);}Complex_t cm_complex_multiply(Complex_t x, Complex_t y){ /* Multiply the two complex numbers and return the result */ Complex_t c; c.real = (x.real * y.real) - (x.imag * y.imag); c.imag = (x.real * y.imag) + (x.imag * y.real); return(c);}Complex_t cm_complex_divide(Complex_t x, Complex_t y){ /* Divide the first number by the second and return the result */ Complex_t c; double mag_y_squared; mag_y_squared = (y.real * y.real) + (y.imag * y.imag); if(mag_y_squared < 1e-100) { printf("\nWARNING: cm_complex_divide() - divide by zero\n"); mag_y_squared = 1e-100; } c.real = ((x.real * y.real) + (x.imag * y.imag)) / mag_y_squared; c.imag = ((x.imag * y.real) - (y.imag * x.real)) / mag_y_squared; return(c);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -