source: trunk/RuntimeLibrary/src/jmi/jmi_block_log.c @ 10867

Last change on this file since 10867 was 10867, checked in by aramle, 21 months ago

#5593 Fixed error output when KIN_REPTD_SYSFUNC_ERR occurs + minor bug fix in IllegalIterationVariableInput.

File size: 9.9 KB
Line 
1/*
2Copyright (C) 2009 Modelon AB
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License version 3 as published
6by the Free Software Foundation, or optionally, under the terms of the
7Common Public License version 1.0 as published by IBM.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License, or the Common Public License, for more details.
13
14You should have received copies of the GNU General Public License
15and the Common Public License along with this program.  If not,
16see <http://www.gnu.org/licenses/> or
17<http://www.ibm.com/developerworks/library/os-cpl.html/> respectively.
18*/
19
20#include <time.h>
21#include <assert.h>
22#include <stdlib.h>
23#include <string.h>
24#include <math.h>
25
26#include "jmi_block_log.h"
27#include "jmi_log.h"
28#include "jmi_block_solver_impl.h"
29
30#define Ith(v,i)    NV_Ith_S(v,i)
31
32int jmi_check_illegal_values(int *error_indicator, jmi_real_t *nominal, jmi_real_t *inputs, int n, int* nans_present, int *infs_present, int *lim_vals_present) {
33    int i, ret = 0;
34    nans_present[0] = FALSE;
35    infs_present[0] = FALSE;
36    lim_vals_present[0] = FALSE;
37    for (i=0;i<n;i++) {
38        double v = inputs[i];
39        /* Recoverable error*/
40        if (v != v) { /* NaN */
41            ret = -1;
42            nans_present[0] = TRUE;
43            error_indicator[i] = 1;
44        } else if(v - v != 0) { /* Inf */
45            ret = -1;
46            infs_present[0] = TRUE;
47            error_indicator[i] = 2;
48        } else if (v >  JMI_LIMIT_VALUE * nominal[i] ||
49            v < -JMI_LIMIT_VALUE * nominal[i]) {
50                ret = -1;
51                lim_vals_present[0] = TRUE;
52                error_indicator[i] = 3;
53        } else {
54            error_indicator[i] = 0;
55        }
56    }
57    return ret;
58}
59
60void jmi_log_illegal_input(jmi_log_t *log, int *error_indicator, int n, int nans_present, int infs_present, int lim_vals_present, jmi_real_t *inputs,
61    jmi_string_t label, int is_iter_var_flag, int* value_references, int log_level, const char* label_type) {
62        int i;
63        char* warn_input_type;
64        char message[256];
65        int ret = (nans_present+infs_present+lim_vals_present) > 0 ? TRUE: FALSE;
66        if (is_iter_var_flag) {
67            warn_input_type = "IllegalIterationVariableInput";
68        } else {
69            warn_input_type = "IllegalVariableInput";
70        }
71
72        if(ret && n==1) {
73            if (nans_present)
74                sprintf(message, "Not a number as input to <%s: %%s>",  label_type);
75            if (infs_present)
76                sprintf(message, "INF as input to <%s: %%s>",  label_type);
77            if( lim_vals_present)
78                sprintf(message, "Absolute value of input too big in <%s: %%s>",  label_type);
79            jmi_log_node(log, logWarning, warn_input_type, message, label);
80        } else if (ret) {
81            jmi_log_node_t outer;
82            jmi_log_node_t inner;
83            sprintf(message, "The iteration variable input is illegal in <%s: %%s>",  label_type);
84            outer = jmi_log_enter_fmt(log, logWarning, warn_input_type, message, label);
85
86            if (nans_present) {
87                inner = jmi_log_enter_vector_(log, outer, logWarning, is_iter_var_flag? "NaNIterationVariableIndices": "NaNVariableIndices");
88                for(i=0; i<n; i++) {
89                    if(error_indicator[i] == 1) {
90                        if (is_iter_var_flag)
91                            jmi_log_vref_(log, 'r', value_references[i]);
92                        else
93                            jmi_log_int_(log, i);
94                    }
95                }
96                jmi_log_leave(log, inner);
97            }
98            if (infs_present) {
99                inner = jmi_log_enter_vector_(log, outer, logWarning,  is_iter_var_flag? "INFIterationVariableIndices": "INFVariableIndices");
100                for(i=0; i<n; i++) {
101                    if(error_indicator[i] == 2) {
102                        if (is_iter_var_flag)
103                            jmi_log_vref_(log, 'r', value_references[i]);
104                        else
105                            jmi_log_int_(log, i);
106                    }
107                }
108                jmi_log_leave(log, inner);
109            }
110            if( lim_vals_present) {
111                inner = jmi_log_enter_vector_(log, outer, logWarning, "LimitingValueIndices");
112                for(i=0; i<n; i++) {
113                    if(error_indicator[i] == 3) {
114                        if (is_iter_var_flag)
115                            jmi_log_vref_(log, 'r', value_references[i]);
116                        else
117                            jmi_log_int_(log, i);
118                    }
119                }
120                jmi_log_leave(log, inner);
121            }
122            if(log_level >= 3) {
123                jmi_log_reals(log, outer, logWarning, is_iter_var_flag?"ivs":"inputs", inputs, n);
124
125            }
126            jmi_log_leave(log, outer);
127        }
128}
129
130void jmi_log_illegal_output(jmi_log_t *log, int *error_indicator, int n_outputs, int n_inputs, jmi_real_t *inputs, jmi_real_t *outputs, int nans_present, int infs_present, int lim_vals_present, 
131    jmi_string_t label, int is_iter_var_flag, int log_level, const char* label_type) {
132        int i;
133        char* warn_output_type;
134        char message[256];
135        int ret = (nans_present+infs_present+lim_vals_present) > 0 ? TRUE: FALSE;
136        if (is_iter_var_flag) {
137            warn_output_type = "IllegalResidualOutput";
138        } else {
139            warn_output_type = "IllegalOutput";
140        }
141
142        if(ret && n_outputs==1 && n_inputs==1) {                       
143            if (nans_present) {
144                sprintf(message, "Not a number as output from <%s: %%s> with <input: %%g>",  label_type);
145                jmi_log_node(log, logWarning, warn_output_type, message, label, inputs[0]);
146            } if (infs_present) {
147                sprintf(message, "INF as output from <%s: %%s> with <input: %%g>",  label_type);
148                jmi_log_node(log, logWarning, warn_output_type, message, label, inputs[0]);
149            } if( lim_vals_present) {
150                sprintf(message, "Absolute value of <output: %%g> too big in <%s: %%s> with <input: %%g>",  label_type);
151                jmi_log_node(log, logWarning, warn_output_type, message, outputs[0],  label, inputs[0]);
152            }
153        } else if (ret) {
154            jmi_log_node_t outer;
155            jmi_log_node_t inner;
156            sprintf(message, "The output is illegal in <%s: %%s>",  label_type);
157            outer = jmi_log_enter_fmt(log, logWarning, warn_output_type, message, label);
158
159            if (nans_present) {
160                if (is_iter_var_flag) {
161                    inner = jmi_log_enter_index_vector_(log, outer, logWarning, "NaNResidualIndices", 'R');
162                } else {
163                    inner = jmi_log_enter_vector_(log, outer, logWarning, "NaNOutputIndices");
164                }
165                for(i=0; i<n_outputs; i++) {
166                    if(error_indicator[i] == 1) {
167                        jmi_log_int_(log, i);
168                    }
169                }
170                jmi_log_leave(log, inner);
171            }
172            if (infs_present) {
173                if (is_iter_var_flag) {
174                    inner = jmi_log_enter_index_vector_(log, outer, logWarning, "INFResidualIndices", 'R');
175                } else {
176                    inner = jmi_log_enter_vector_(log, outer, logWarning, "INFOutputIndices");
177                }
178                for(i=0; i<n_outputs; i++) {
179                    if(error_indicator[i] == 2) {
180                        jmi_log_int_(log, i);
181                    }
182                }
183                jmi_log_leave(log, inner);
184            }
185            if( lim_vals_present) {
186                if (is_iter_var_flag) {
187                    inner = jmi_log_enter_index_vector_(log, outer, logWarning, "LimitingValueIndices", 'R');
188                } else {
189                    inner = jmi_log_enter_vector_(log, outer, logWarning, "LimitingValueIndicess");
190                }
191                for(i=0; i<n_outputs; i++) {
192                    if(error_indicator[i] == 3) {
193                        jmi_log_int_(log, i);
194                    }
195                }
196                jmi_log_leave(log, inner);
197            }
198            if(log_level >= 3) {
199                jmi_log_reals(log, outer, logWarning, is_iter_var_flag?"ivs":"inputs", inputs, n_inputs);
200                jmi_log_reals(log, outer, logWarning,  is_iter_var_flag?"residuals":"outputs", outputs, n_outputs); 
201
202            }
203            jmi_log_leave(log, outer);
204        }
205}
206
207int jmi_check_and_log_illegal_residual_output(jmi_block_solver_t *block, double* f, double* ivs, double* residual_heuristic_nominal, int N) {
208    int ret=0;
209    jmi_log_t *log = block->log;
210    int nans_present = FALSE;
211    int infs_present = FALSE;
212    int lim_vals_present = FALSE;
213
214    ret = jmi_check_illegal_values(block->residual_error_indicator, residual_heuristic_nominal, f, N, &nans_present, &infs_present, &lim_vals_present);
215    jmi_log_illegal_output(log, block->residual_error_indicator, N, N, ivs, f, nans_present, infs_present, lim_vals_present, block->label, TRUE, block->callbacks->log_options.log_level, "block");
216
217    /* Set illegal residual output as a recoverable error from Kinsol */
218    return -ret;
219}
220
221
222
223int jmi_check_and_log_illegal_iv_input(jmi_block_solver_t *block, double* ivs, int N) {
224    int ret = 0;
225    jmi_log_t *log = block->log;
226    int nans_present = FALSE;
227    int infs_present = FALSE;
228    int lim_vals_present = FALSE;
229
230    ret = jmi_check_illegal_values(block->residual_error_indicator, block->nominal, ivs, N, &nans_present, &infs_present, &lim_vals_present);
231
232    jmi_log_illegal_input(log, block->residual_error_indicator, N, nans_present, infs_present, 
233        lim_vals_present, ivs, block->label, TRUE, block->value_references, block->callbacks->log_options.log_level, "block");
234
235    return ret;
236}
Note: See TracBrowser for help on using the repository browser.