1/*.......1.........2.........3.........4.........5.........6.........7.........8 2================================================================================ 3 4FILE divide/cfunc.mod 5 6Public Domain 7 8Georgia Tech Research Corporation 9Atlanta, Georgia 30332 10PROJECT A-8503-405 11 12 13AUTHORS 14 15 6 Jun 1991 Jeffrey P. Murray 16 17 18MODIFICATIONS 19 20 2 Oct 1991 Jeffrey P. Murray 21 22 23SUMMARY 24 25 This file contains the model-specific routines used to 26 functionally describe the divide code model. 27 28 29INTERFACES 30 31 FILE ROUTINE CALLED 32 33 CMutil.c void cm_smooth_corner(); 34 35 36REFERENCED FILES 37 38 Inputs from and outputs to ARGS structure. 39 40 41NON-STANDARD FEATURES 42 43 NONE 44 45===============================================================================*/ 46 47/*=== INCLUDE FILES ====================*/ 48 49#include <math.h> 50 51 52 53/*=== CONSTANTS ========================*/ 54 55 56 57 58/*=== MACROS ===========================*/ 59 60 61 62 63/*=== LOCAL VARIABLES & TYPEDEFS =======*/ 64 65 66 67 68/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ 69 70 71 72 73 74/*============================================================================== 75 76FUNCTION void cm_divide() 77 78AUTHORS 79 80 2 Oct 1991 Jeffrey P. Murray 81 82MODIFICATIONS 83 84 NONE 85 86SUMMARY 87 88 This function implements the divide code model. 89 90INTERFACES 91 92 FILE ROUTINE CALLED 93 94 CMutil.c void cm_smooth_corner(); 95 96RETURNED VALUE 97 98 Returns inputs and outputs via ARGS structure. 99 100GLOBAL VARIABLES 101 102 NONE 103 104NON-STANDARD FEATURES 105 106 NONE 107 108==============================================================================*/ 109 110 111/*=== CM_DIVIDE ROUTINE ===*/ 112 113 114void cm_divide(ARGS) 115 116{ 117 double den_lower_limit; /* denominator lower limit */ 118 double den_domain; /* smoothing range for the lower limit */ 119 double threshold_upper; /* value above which smoothing occurs */ 120 double threshold_lower; /* value below which smoothing occurs */ 121 double numerator; /* numerator input */ 122 double denominator; /* denominator input */ 123 double limited_den; /* denominator value if limiting is needed */ 124 double den_partial; /* partial of the output wrt denominator */ 125 double out_gain; /* output gain */ 126 double num_gain; /* numerator gain */ 127 double den_gain; /* denominator gain */ 128 129 Mif_Complex_t ac_gain; 130 131 132 133 /* Retrieve frequently used parameters... */ 134 135 den_lower_limit = PARAM(den_lower_limit); 136 den_domain = PARAM(den_domain); 137 out_gain = PARAM(out_gain); 138 num_gain = PARAM(num_gain); 139 den_gain = PARAM(den_gain); 140 141 142 if (PARAM(fraction) == MIF_TRUE) /* Set domain to absolute value */ 143 den_domain = den_domain * den_lower_limit; 144 145 threshold_upper = den_lower_limit + /* Set Upper Threshold */ 146 den_domain; 147 148 threshold_lower = den_lower_limit - /* Set Lower Threshold */ 149 den_domain; 150 151 numerator = (INPUT(num) + PARAM(num_offset)) * num_gain; 152 denominator = (INPUT(den) + PARAM(den_offset)) * den_gain; 153 154 if ((denominator < threshold_upper) && (denominator >= 0)) { /* Need to limit den...*/ 155 156 if (denominator > threshold_lower) /* Parabolic Region */ 157 cm_smooth_corner(denominator,den_lower_limit, 158 den_lower_limit,den_domain,0.0,1.0, 159 &limited_den,&den_partial); 160 161 else { /* Hard-Limited Region */ 162 limited_den = den_lower_limit; 163 den_partial = 0.0; 164 } 165 } 166 else 167 if ((denominator > -threshold_upper) && (denominator < 0)) { /* Need to limit den...*/ 168 if (denominator < -threshold_lower) /* Parabolic Region */ 169 cm_smooth_corner(denominator,-den_lower_limit, 170 -den_lower_limit,den_domain,0.0,1.0, 171 &limited_den,&den_partial); 172 173 else { /* Hard-Limited Region */ 174 limited_den = -den_lower_limit; 175 den_partial = 0.0; 176 } 177 } 178 else { /* No limiting needed */ 179 limited_den = denominator; 180 den_partial = 1.0; 181 } 182 183 if (ANALYSIS != MIF_AC) { 184 185 OUTPUT(out) = PARAM(out_offset) + out_gain * 186 ( numerator/limited_den ); 187 PARTIAL(out,num) = out_gain * num_gain / limited_den; 188 PARTIAL(out,den) = -out_gain * numerator * den_gain * 189 den_partial / (limited_den * limited_den); 190 191 } 192 else { 193 ac_gain.real = out_gain * num_gain / limited_den; 194 ac_gain.imag= 0.0; 195 AC_GAIN(out,num) = ac_gain; 196 197 ac_gain.real = -out_gain * numerator * den_gain * 198 den_partial / (limited_den * limited_den); 199 ac_gain.imag= 0.0; 200 AC_GAIN(out,den) = ac_gain; 201 } 202 203} 204