analog/{sine,square,triangle}, xtradev/core, change array access

avoid copy of parameter array,
which would need to be freed to avoid a memory leak

this is a modified and partial version of a patch provided by
Krzysztof Blaszkowski <kb@sysmikro.com.pl>
This commit is contained in:
rlar 2013-12-30 17:19:07 +01:00
parent 91449d438c
commit 70f12fb1fd
6 changed files with 72 additions and 195 deletions

View File

@ -72,13 +72,6 @@ char *array_error = "\n**** Error ****\nSINE: Size of control array different th
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
typedef struct {
double *control; /* the storage array for the
control vector (cntl_array) */
double *freq; /* the storage array for the
frequency vector (freq_array) */
} Local_Data_t;
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
@ -133,8 +126,8 @@ cm_sine(ARGS)
int cntl_size; /* control array size */
int freq_size; /* frequency array size */
double *x; /* pointer to the control array values */
double *y; /* pointer to the frequency array values */
Mif_Value_t *x; /* pointer to the control array values */
Mif_Value_t *y; /* pointer to the frequency array values */
double cntl_input; /* control input */
double dout_din; /* partial derivative of output wrt control in */
double output_low; /* output low value */
@ -148,9 +141,6 @@ cm_sine(ARGS)
Mif_Complex_t ac_gain;
Local_Data_t *loc; /* Pointer to local static data, not to be included
in the state vector */
/**** Retrieve frequently used parameters... ****/
cntl_size = PARAM_SIZE(cntl_array);
@ -167,24 +157,11 @@ cm_sine(ARGS)
cm_analog_alloc(INT1, sizeof(double));
/*** allocate static storage for *loc ***/
STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t));
loc = STATIC_VAR(locdata);
/* Allocate storage for breakpoint domain & freq. range values */
x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double));
if (!x) {
cm_message_send(allocation_error);
return;
}
y = loc->freq = (double *) calloc((size_t) freq_size, sizeof(double));
if (!y) {
cm_message_send(allocation_error);
return;
}
}
x = (Mif_Value_t*) &PARAM(cntl_array[0]);
y = (Mif_Value_t*) &PARAM(freq_array[0]);
if (ANALYSIS == MIF_DC) {
OUTPUT(out) = (output_hi + output_low) / 2;
@ -197,38 +174,27 @@ cm_sine(ARGS)
phase = (double *) cm_analog_get_ptr(INT1, 0);
phase1 = (double *) cm_analog_get_ptr(INT1, 1);
loc = STATIC_VAR(locdata);
x = loc->control;
y = loc->freq;
/* Retrieve x and y values. */
for (i = 0; i < cntl_size; i++) {
x[i] = PARAM(cntl_array[i]);
y[i] = PARAM(freq_array[i]);
}
/* Retrieve cntl_input value. */
cntl_input = INPUT(cntl_in);
/* Determine segment boundaries within which cntl_input resides */
if (cntl_input <= *x) {
if (cntl_input <= x[0].rvalue) {
/*** cntl_input below lowest cntl_voltage ***/
dout_din = (y[1] - y[0]) / (x[1] - x[0]);
freq = *y + (cntl_input - *x) * dout_din;
dout_din = (y[1].rvalue - y[0].rvalue) / (x[1].rvalue - x[0].rvalue);
freq = y[0].rvalue + (cntl_input - x[0].rvalue) * dout_din;
if (freq <= 0) {
cm_message_send(sine_freq_clamp);
freq = 1e-16;
}
} else if (cntl_input >= x[cntl_size-1]) {
} else if (cntl_input >= x[cntl_size-1].rvalue) {
/*** cntl_input above highest cntl_voltage ***/
dout_din = (y[cntl_size-1] - y[cntl_size-2]) /
(x[cntl_size-1] - x[cntl_size-2]);
freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * dout_din;
dout_din = (y[cntl_size-1].rvalue - y[cntl_size-2].rvalue) /
(x[cntl_size-1].rvalue - x[cntl_size-2].rvalue);
freq = y[cntl_size-1].rvalue + (cntl_input - x[cntl_size-1].rvalue) * dout_din;
} else {
@ -237,10 +203,10 @@ cm_sine(ARGS)
calculate required output. ***/
for (i = 0; i < cntl_size - 1; i++)
if ((cntl_input < x[i+1]) && (cntl_input >= x[i])) {
if ((cntl_input < x[i+1].rvalue) && (cntl_input >= x[i].rvalue)) {
/* Interpolate to the correct frequency value */
freq = ((cntl_input - x[i]) / (x[i+1] - x[i])) *
(y[i+1] - y[i]) + y[i];
freq = ((cntl_input - x[i].rvalue) / (x[i+1].rvalue - x[i].rvalue)) *
(y[i+1].rvalue - y[i].rvalue) + y[i].rvalue;
}
}

View File

@ -58,9 +58,3 @@ Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
STATIC_VAR_TABLE:
Static_Var_Name: locdata
Description: "local static data"
Data_Type: pointer

View File

@ -74,10 +74,6 @@ char *square_array_error = "\n**** Error ****\nSQUARE: Size of control array dif
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
typedef struct {
double *control; /* the storage array for the
control vector (cntl_array) */
double *freq; /* the storage array for the
pulse width array (pw_array) */
Boolean_t tran_init; /* for initialization of phase1) */
} Local_Data_t;
@ -159,8 +155,8 @@ cm_square(ARGS)
int freq_size; /* frequency array size */
int int_cycle; /* integer number of cycles */
double *x; /* pointer to the control array values */
double *y; /* pointer to the frequecy array values */
Mif_Value_t *x; /* pointer to the control array values */
Mif_Value_t *y; /* pointer to the frequency array values */
double cntl_input; /* control input */
double dout_din; /* slope of the frequency array wrt the control
array. Used to extrapolate a frequency above
@ -218,21 +214,12 @@ cm_square(ARGS)
STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t));
loc = STATIC_VAR(locdata);
/* Allocate storage for breakpoint domain & pulse width values */
x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double));
if (!x) {
cm_message_send(square_allocation_error);
return;
}
y = loc->freq = (double *) calloc((size_t) freq_size, sizeof(double));
if (!y) {
cm_message_send(square_allocation_error);
return;
}
loc->tran_init = FALSE;
}
x = (Mif_Value_t*) &PARAM(cntl_array[0]);
y = (Mif_Value_t*) &PARAM(freq_array[0]);
if (ANALYSIS == MIF_DC) {
/* initialize time values */
@ -267,39 +254,31 @@ cm_square(ARGS)
time4 = *t4;
loc = STATIC_VAR(locdata);
x = loc->control;
y = loc->freq;
if (!loc->tran_init) {
*phase1 = 0.0;
loc->tran_init = TRUE;
}
/* Retrieve x and y values. */
for (i = 0; i < cntl_size; i++) {
x[i] = PARAM(cntl_array[i]);
y[i] = PARAM(freq_array[i]);
}
/* Retrieve cntl_input value. */
cntl_input = INPUT(cntl_in);
/* Determine segment boundaries within which cntl_input resides */
/*** cntl_input below lowest cntl_voltage ***/
if (cntl_input <= *x) {
dout_din = (y[1] - y[0]) / (x[1] - x[0]);
freq = *y + (cntl_input - *x) * dout_din;
if (cntl_input <= x[0].rvalue) {
dout_din = (y[1].rvalue - y[0].rvalue) / (x[1].rvalue - x[0].rvalue);
freq = y[0].rvalue + (cntl_input - x[0].rvalue) * dout_din;
if (freq <= 0) {
cm_message_send(square_freq_clamp);
freq = 1e-16;
}
} else if (cntl_input >= x[cntl_size-1]) {
} else if (cntl_input >= x[cntl_size-1].rvalue) {
/*** cntl_input above highest cntl_voltage ***/
dout_din = (y[cntl_size-1] - y[cntl_size-2]) /
(x[cntl_size-1] - x[cntl_size-2]);
freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * dout_din;
dout_din = (y[cntl_size-1].rvalue - y[cntl_size-2].rvalue) /
(x[cntl_size-1].rvalue - x[cntl_size-2].rvalue);
freq = y[cntl_size-1].rvalue + (cntl_input - x[cntl_size-1].rvalue) * dout_din;
} else {
/*** cntl_input within bounds of end midpoints...
@ -308,12 +287,12 @@ cm_square(ARGS)
for (i = 0; i < cntl_size - 1; i++) {
if ((cntl_input < x[i+1]) && (cntl_input >= x[i])) {
if ((cntl_input < x[i+1].rvalue) && (cntl_input >= x[i].rvalue)) {
/* Interpolate to the correct frequency value */
freq = ((cntl_input - x[i])/(x[i+1] - x[i])) *
(y[i+1]-y[i]) + y[i];
freq = ((cntl_input - x[i].rvalue)/(x[i+1].rvalue - x[i].rvalue)) *
(y[i+1].rvalue-y[i].rvalue) + y[i].rvalue;
}
}

View File

@ -73,10 +73,6 @@ char *triangle_array_error = "\n**** Error ****\nTRIANGLE: Size of control array
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
typedef struct {
double *control; /* the storage array for the
control vector (cntl_array) */
double *freq; /* the storage array for the
pulse width array (pw_array) */
int tran_init; /* for initialization of phase1) */
} Local_Data_t;
@ -159,8 +155,8 @@ cm_triangle(ARGS)
int freq_size; /* size of the frequency array */
int int_cycle; /* the number of cycles rounded to the nearest int */
double *x; /* pointer holds the values of the control array */
double *y; /* pointer holds the values of the freq array */
Mif_Value_t *x; /* pointer holds the values of the control array */
Mif_Value_t *y; /* pointer holds the values of the freq array */
double cntl_input; /* control input */
double dout_din; /* partial out wrt to control input */
@ -209,21 +205,12 @@ cm_triangle(ARGS)
STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t));
loc = STATIC_VAR(locdata);
/* Allocate storage for breakpoint domain & pulse width values */
x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double));
if (!x) {
cm_message_send(triangle_allocation_error);
return;
}
y = loc->freq = (double *) calloc((size_t) freq_size, sizeof(double));
if (!y) {
cm_message_send(triangle_allocation_error);
return;
}
loc->tran_init = FALSE;
}
x = (Mif_Value_t*) &PARAM(cntl_array[0]);
y = (Mif_Value_t*) &PARAM(freq_array[0]);
if (ANALYSIS == MIF_DC) {
/* initialize time values */
@ -255,42 +242,34 @@ cm_triangle(ARGS)
t_start = *t_end;
loc = STATIC_VAR(locdata);
x = loc->control;
y = loc->freq;
if (! loc->tran_init) {
*phase1 = 0.0;
loc->tran_init = TRUE;
}
/* Retrieve x and y values. */
for (i = 0; i < cntl_size; i++) {
x[i] = PARAM(cntl_array[i]);
y[i] = PARAM(freq_array[i]);
}
/* Retrieve cntl_input value. */
cntl_input = INPUT(cntl_in);
/* Determine segment boundaries within which cntl_input resides */
/*** cntl_input below lowest cntl_voltage ***/
if (cntl_input <= *x) {
if (cntl_input <= x[0].rvalue) {
dout_din = (y[1] - y[0]) / (x[1] - x[0]);
freq = *y + (cntl_input - *x) * dout_din;
dout_din = (y[1].rvalue - y[0].rvalue) / (x[1].rvalue - x[0].rvalue);
freq = y[0].rvalue + (cntl_input - x[0].rvalue) * dout_din;
if (freq <= 0) {
cm_message_send(triangle_freq_clamp);
freq = 1e-16;
}
} else if (cntl_input >= x[cntl_size-1]) {
} else if (cntl_input >= x[cntl_size-1].rvalue) {
/*** cntl_input above highest cntl_voltage ***/
dout_din = (y[cntl_size-1] - y[cntl_size-2]) /
(x[cntl_size-1] - x[cntl_size-2]);
freq = y[cntl_size-1] + (cntl_input - x[cntl_size-1]) * dout_din;
/* freq = y[cntl_size-1]; */
dout_din = (y[cntl_size-1].rvalue - y[cntl_size-2].rvalue) /
(x[cntl_size-1].rvalue - x[cntl_size-2].rvalue);
freq = y[cntl_size-1].rvalue + (cntl_input - x[cntl_size-1].rvalue) * dout_din;
/* freq = y[cntl_size-1].rvalue; */
} else {
/*** cntl_input within bounds of end midpoints...
@ -299,12 +278,12 @@ cm_triangle(ARGS)
for (i = 0; i < cntl_size - 1; i++) {
if ((cntl_input < x[i+1]) && (cntl_input >= x[i])) {
if ((cntl_input < x[i+1].rvalue) && (cntl_input >= x[i].rvalue)) {
/* Interpolate to the correct frequency value */
freq = ((cntl_input - x[i]) / (x[i+1] - x[i])) *
(y[i+1] - y[i]) + y[i];
freq = ((cntl_input - x[i].rvalue) / (x[i+1].rvalue - x[i].rvalue)) *
(y[i+1].rvalue - y[i].rvalue) + y[i].rvalue;
}
}
}

View File

@ -66,14 +66,6 @@ NON-STANDARD FEATURES
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
typedef struct {
double *H_array; /* the storage array for the
control vector (cntl_array) */
double *B_array; /* the storage array for the
pulse width array (pw_array) */
Boolean_t tran_init; /* for initialization of phase1) */
} Local_Data_t;
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
@ -197,8 +189,8 @@ cm_core(ARGS)
double input_domain; /* smoothing range */
double *H; /* pointer to the H-field array */
double *B; /* pointer to the B-field array */
Mif_Value_t *H; /* pointer to the H-field array */
Mif_Value_t *B; /* pointer to the B-field array */
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 */
@ -216,7 +208,6 @@ cm_core(ARGS)
Mif_Complex_t ac_gain;
char *allocation_error="\n***ERROR***\nCORE: Allocation calloc failed!\n";
char *limit_error="\n***ERROR***\nCORE: Violation of 50% rule in breakpoints!\n";
@ -250,9 +241,6 @@ cm_core(ARGS)
in_low - hyst and +infinity */
*old_hyst_state; /* previous value of *hyst_state */
Local_Data_t *loc; /* Pointer to local static data, not to be included
in the state vector */
/* Retrieve mode parameter... */
mode = PARAM(mode);
@ -270,40 +258,14 @@ cm_core(ARGS)
size = PARAM_SIZE(H_array);
if (INIT == 1) {
/*** allocate static storage for *loc ***/
STATIC_VAR(locdata) = calloc(1, sizeof(Local_Data_t));
loc = STATIC_VAR(locdata);
/* Allocate storage for breakpoint domain & range values */
H = loc->H_array = (double *) calloc((size_t) size, sizeof(double));
if (!H) {
cm_message_send(allocation_error);
return;
}
B = loc->B_array = (double *) calloc((size_t) size, sizeof(double));
if (!B) {
cm_message_send(allocation_error);
return;
}
}
loc = STATIC_VAR(locdata);
H = loc->H_array;
B = loc->B_array;
/* Retrieve H and B values. */
for (i = 0; i < size; i++) {
H[i] = PARAM(H_array[i]);
B[i] = PARAM(B_array[i]);
}
H = (Mif_Value_t*) &PARAM(H_array[0]);
B = (Mif_Value_t*) &PARAM(B_array[0]);
/* See if input_domain is absolute...if so, test against */
/* breakpoint segments for violation of 50% rule... */
if (PARAM(fraction) == MIF_FALSE)
for (i = 0; i < size - 1; i++)
if ((H[i+1] - H[i]) < 2.0 * input_domain) {
if ((H[i+1].rvalue - H[i].rvalue) < 2.0 * input_domain) {
cm_message_send(limit_error);
return;
}
@ -316,28 +278,31 @@ cm_core(ARGS)
/* Determine segment boundaries within which H_input resides */
if (H_input <= (H[1] + H[0]) / 2.0) {/*** H_input below lowest midpoint ***/
if (H_input <= (H[1].rvalue + H[0].rvalue) / 2.0) {/*** H_input below lowest midpoint ***/
dout_din = (B[1] - B[0]) / (H[1] - H[0]);
B_out = *B + (H_input - *H) * dout_din;
dout_din = (B[1].rvalue - B[0].rvalue) / (H[1].rvalue - H[0].rvalue);
B_out = B[0].rvalue + (H_input - H[0].rvalue) * dout_din;
} else if (H_input >= (H[size-2] + H[size-1]) / 2.0) {
} else if (H_input >= (H[size-2].rvalue + H[size-1].rvalue) / 2.0) {
/*** H_input above highest midpoint ***/
dout_din = (B[size-1] - B[size-2]) / (H[size-1] - H[size-2]);
B_out = B[size-1] + (H_input - H[size-1]) * dout_din;
dout_din = (B[size-1].rvalue - B[size-2].rvalue) / (H[size-1].rvalue - H[size-2].rvalue);
B_out = B[size-1].rvalue + (H_input - H[size-1].rvalue) * dout_din;
} else { /*** H_input within bounds of end midpoints... ***/
/*** must determine position progressively & then ***/
/*** calculate required output. ***/
dout_din = 0.0 / 0.0;
B_out = 0.0 / 0.0;
for (i = 1; i < size; i++)
if (H_input < (H[i] + H[i+1]) / 2.0) {
if (H_input < (H[i].rvalue + H[i+1].rvalue) / 2.0) {
/* approximate position known... */
lower_seg = (H[i] - H[i-1]);
upper_seg = (H[i+1] - H[i]);
lower_seg = (H[i].rvalue - H[i-1].rvalue);
upper_seg = (H[i+1].rvalue - H[i].rvalue);
/* Calculate input_domain about this region's breakpoint.*/
@ -354,27 +319,27 @@ cm_core(ARGS)
}
/* Set up threshold values about breakpoint... */
threshold_lower = H[i] - input_domain;
threshold_upper = H[i] + input_domain;
threshold_lower = H[i].rvalue - input_domain;
threshold_upper = H[i].rvalue + input_domain;
/* Determine where H_input is within region & determine */
/* output and partial values.... */
if (H_input < threshold_lower) { /* Lower linear region */
dout_din = (B[i] - B[i-1]) / lower_seg;
B_out = B[i] + (H_input - H[i]) * dout_din;
dout_din = (B[i].rvalue - B[i-1].rvalue) / lower_seg;
B_out = B[i].rvalue + (H_input - H[i].rvalue) * dout_din;
} else if (H_input < threshold_upper) { /* Parabolic region */
lower_slope = (B[i] - B[i-1]) / lower_seg;
upper_slope = (B[i+1] - B[i]) / upper_seg;
cm_smooth_corner(H_input, H[i], B[i], input_domain,
lower_slope = (B[i].rvalue - B[i-1].rvalue) / lower_seg;
upper_slope = (B[i+1].rvalue - B[i].rvalue) / upper_seg;
cm_smooth_corner(H_input, H[i].rvalue, B[i].rvalue, input_domain,
lower_slope, upper_slope, &B_out, &dout_din);
} else { /* Upper linear region */
dout_din = (B[i+1] - B[i]) / upper_seg;
B_out = B[i] + (H_input - H[i]) * dout_din;
dout_din = (B[i+1].rvalue - B[i].rvalue) / upper_seg;
B_out = B[i].rvalue + (H_input - H[i].rvalue) * dout_din;
}

View File

@ -131,9 +131,3 @@ Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: locdata
Description: "local static data"
Data_Type: pointer