GnmFunc: make this a GObject.
[gnumeric.git] / src / tools / analysis-sign-test.c
blob604ef5831ece94bea28bd24a1d019c151c41a487
1 /*
2 * analysis-sign-test.c:
4 * Author:
5 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
7 * (C) Copyright 2009 by Andreas J. Guelzow <aguelzow@pyrshep.ca>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
26 #include <gnumeric.h>
27 #include <tools/analysis-sign-test.h>
28 #include <tools/analysis-tools.h>
29 #include <value.h>
30 #include <ranges.h>
31 #include <expr.h>
32 #include <func.h>
33 #include <numbers.h>
35 static gboolean
36 analysis_tool_sign_test_engine_run (data_analysis_output_t *dao,
37 analysis_tools_data_sign_test_t *info)
39 guint col;
40 GSList *data = info->base.input;
41 gboolean first = TRUE;
43 GnmExpr const *expr;
44 GnmExpr const *expr_neg;
45 GnmExpr const *expr_pos;
46 GnmExpr const *expr_isnumber;
48 GnmFunc *fd_median;
49 GnmFunc *fd_if;
50 GnmFunc *fd_sum;
51 GnmFunc *fd_min;
52 GnmFunc *fd_binomdist;
53 GnmFunc *fd_isnumber;
54 GnmFunc *fd_iferror;
56 fd_median = gnm_func_lookup_or_add_placeholder ("MEDIAN");
57 gnm_func_inc_usage (fd_median);
58 fd_if = gnm_func_lookup_or_add_placeholder ("IF");
59 gnm_func_inc_usage (fd_if);
60 fd_sum = gnm_func_lookup_or_add_placeholder ("SUM");
61 gnm_func_inc_usage (fd_sum);
62 fd_min = gnm_func_lookup_or_add_placeholder ("MIN");
63 gnm_func_inc_usage (fd_min);
64 fd_binomdist = gnm_func_lookup_or_add_placeholder ("BINOMDIST");
65 gnm_func_inc_usage (fd_binomdist);
66 fd_isnumber = gnm_func_lookup_or_add_placeholder ("ISNUMBER");
67 gnm_func_inc_usage (fd_isnumber);
68 fd_iferror = gnm_func_lookup_or_add_placeholder ("IFERROR");
69 gnm_func_inc_usage (fd_iferror);
71 dao_set_italic (dao, 0, 0, 0, 9);
72 set_cell_text_col (dao, 0, 0, _("/Sign Test"
73 "/Median"
74 "/Predicted Median"
75 "/Test Statistic"
76 "/N"
77 "/\xce\xb1"
78 "/P(T\xe2\x89\xa4t) one-tailed"
79 "/P(T\xe2\x89\xa4t) two-tailed"));
81 for (col = 0; data != NULL; data = data->next, col++) {
82 GnmValue *val_org = value_dup (data->data);
83 GnmExpr const *expr_org;
85 /* Note that analysis_tools_write_label may modify val_org */
86 dao_set_italic (dao, col + 1, 0, col+1, 0);
87 analysis_tools_write_label (val_org, dao, &info->base, col + 1, 0, col + 1);
88 expr_org = gnm_expr_new_constant (val_org);
90 if (first) {
91 dao_set_cell_float (dao, col + 1, 2, info->median);
92 dao_set_cell_float (dao, col + 1, 5, info->alpha);
93 first = FALSE;
94 } else {
95 dao_set_cell_expr (dao, col + 1, 2, make_cellref (-1,0));
96 dao_set_cell_expr (dao, col + 1, 5, make_cellref (-1,0));
99 expr_isnumber = gnm_expr_new_funcall3
100 (fd_if, gnm_expr_new_funcall1
101 (fd_isnumber, gnm_expr_copy (expr_org)),
102 gnm_expr_new_constant (value_new_int (1)),
103 gnm_expr_new_constant (value_new_int (0)));
105 expr = gnm_expr_new_funcall1
106 (fd_median,
107 gnm_expr_copy (expr_org));
108 dao_set_cell_expr (dao, col + 1, 1, expr);
110 expr_neg = gnm_expr_new_funcall1
111 (fd_sum,
112 gnm_expr_new_binary
113 (gnm_expr_copy (expr_isnumber), GNM_EXPR_OP_MULT,
114 gnm_expr_new_funcall2
115 (fd_iferror,
116 gnm_expr_new_funcall3
117 (fd_if, gnm_expr_new_binary (gnm_expr_copy (expr_org),
118 GNM_EXPR_OP_LT, make_cellref (0,-1)),
119 gnm_expr_new_constant (value_new_int (1)),
120 gnm_expr_new_constant (value_new_int (0))),
121 gnm_expr_new_constant (value_new_int (0)))));
122 expr_pos = gnm_expr_new_funcall1
123 (fd_sum,
124 gnm_expr_new_binary
125 (gnm_expr_copy (expr_isnumber), GNM_EXPR_OP_MULT,
126 gnm_expr_new_funcall2
127 (fd_iferror,
128 gnm_expr_new_funcall3
129 (fd_if, gnm_expr_new_binary (gnm_expr_copy (expr_org),
130 GNM_EXPR_OP_GT, make_cellref (0,-1)),
131 gnm_expr_new_constant (value_new_int (1)),
132 gnm_expr_new_constant (value_new_int (0))),
133 gnm_expr_new_constant (value_new_int (0)))));
134 expr = gnm_expr_new_funcall2
135 (fd_min, expr_neg, expr_pos);
136 dao_set_cell_array_expr (dao, col + 1, 3, expr);
138 expr = gnm_expr_new_funcall1
139 (fd_sum, gnm_expr_new_binary
140 (expr_isnumber, GNM_EXPR_OP_MULT,
141 gnm_expr_new_funcall2
142 (fd_iferror, gnm_expr_new_funcall3
143 (fd_if, gnm_expr_new_binary (expr_org,
144 GNM_EXPR_OP_NOT_EQUAL, make_cellref (0,-2)),
145 gnm_expr_new_constant (value_new_int (1)),
146 gnm_expr_new_constant (value_new_int (0))),
147 gnm_expr_new_constant (value_new_int (0)))));
148 dao_set_cell_array_expr (dao, col + 1, 4, expr);
150 expr = gnm_expr_new_funcall4 (fd_binomdist, make_cellref (0,-3), make_cellref (0,-2),
151 gnm_expr_new_constant (value_new_float (0.5)),
152 gnm_expr_new_constant (value_new_bool (TRUE)));
153 dao_set_cell_array_expr (dao, col + 1, 6, expr);
155 expr = gnm_expr_new_binary (gnm_expr_new_constant (value_new_int (2)),
156 GNM_EXPR_OP_MULT, make_cellref (0,-1));
157 dao_set_cell_array_expr (dao, col + 1, 7, expr);
160 gnm_func_dec_usage (fd_median);
161 gnm_func_dec_usage (fd_if);
162 gnm_func_dec_usage (fd_min);
163 gnm_func_dec_usage (fd_sum);
164 gnm_func_dec_usage (fd_binomdist);
165 gnm_func_dec_usage (fd_isnumber);
166 gnm_func_dec_usage (fd_iferror);
168 dao_redraw_respan (dao);
170 return FALSE;
173 static gboolean
174 analysis_tool_sign_test_two_engine_run (data_analysis_output_t *dao,
175 analysis_tools_data_sign_test_two_t *info)
177 GnmValue *val_1;
178 GnmValue *val_2;
180 GnmExpr const *expr_1;
181 GnmExpr const *expr_2;
183 GnmExpr const *expr;
184 GnmExpr const *expr_diff;
185 GnmExpr const *expr_neg;
186 GnmExpr const *expr_pos;
187 GnmExpr const *expr_isnumber_1;
188 GnmExpr const *expr_isnumber_2;
190 GnmFunc *fd_median;
191 GnmFunc *fd_if;
192 GnmFunc *fd_sum;
193 GnmFunc *fd_min;
194 GnmFunc *fd_binomdist;
195 GnmFunc *fd_isnumber;
196 GnmFunc *fd_iferror;
198 fd_median = gnm_func_lookup_or_add_placeholder ("MEDIAN");
199 gnm_func_inc_usage (fd_median);
200 fd_if = gnm_func_lookup_or_add_placeholder ("IF");
201 gnm_func_inc_usage (fd_if);
202 fd_sum = gnm_func_lookup_or_add_placeholder ("SUM");
203 gnm_func_inc_usage (fd_sum);
204 fd_min = gnm_func_lookup_or_add_placeholder ("MIN");
205 gnm_func_inc_usage (fd_min);
206 fd_binomdist = gnm_func_lookup_or_add_placeholder ("BINOMDIST");
207 gnm_func_inc_usage (fd_binomdist);
208 fd_isnumber = gnm_func_lookup_or_add_placeholder ("ISNUMBER");
209 gnm_func_inc_usage (fd_isnumber);
210 fd_iferror = gnm_func_lookup_or_add_placeholder ("IFERROR");
211 gnm_func_inc_usage (fd_iferror);
213 dao_set_italic (dao, 0, 0, 0, 9);
214 set_cell_text_col (dao, 0, 0, _("/Sign Test"
215 "/Median"
216 "/Predicted Difference"
217 "/Test Statistic"
218 "/N"
219 "/\xce\xb1"
220 "/P(T\xe2\x89\xa4t) one-tailed"
221 "/P(T\xe2\x89\xa4t) two-tailed"));
223 val_1 = value_dup (info->base.range_1);
224 val_2 = value_dup (info->base.range_2);
226 /* Labels */
227 dao_set_italic (dao, 1, 0, 2, 0);
228 analysis_tools_write_label_ftest (val_1, dao, 1, 0,
229 info->base.labels, 1);
230 analysis_tools_write_label_ftest (val_2, dao, 2, 0,
231 info->base.labels, 2);
233 expr_1 = gnm_expr_new_constant (value_dup (val_1));
234 expr_2 = gnm_expr_new_constant (value_dup (val_2));
236 dao_set_cell_float (dao, 1, 2, info->median);
237 dao_set_cell_float (dao, 1, 5, info->base.alpha);
239 expr = gnm_expr_new_funcall1
240 (fd_median,
241 gnm_expr_copy (expr_1));
242 dao_set_cell_expr (dao, 1, 1, expr);
244 expr = gnm_expr_new_funcall1
245 (fd_median,
246 gnm_expr_copy (expr_2));
247 dao_set_cell_expr (dao, 2, 1, expr);
249 expr_diff = gnm_expr_new_binary (gnm_expr_copy (expr_1),
250 GNM_EXPR_OP_SUB,
251 gnm_expr_copy (expr_2));
253 expr_isnumber_1 = gnm_expr_new_funcall3
254 (fd_if, gnm_expr_new_funcall1
255 (fd_isnumber, expr_1),
256 gnm_expr_new_constant (value_new_int (1)),
257 gnm_expr_new_constant (value_new_int (0)));
258 expr_isnumber_2 = gnm_expr_new_funcall3
259 (fd_if, gnm_expr_new_funcall1
260 (fd_isnumber, expr_2),
261 gnm_expr_new_constant (value_new_int (1)),
262 gnm_expr_new_constant (value_new_int (0)));
264 expr_neg = gnm_expr_new_funcall1
265 (fd_sum,
266 gnm_expr_new_binary
267 (gnm_expr_copy (expr_isnumber_1), GNM_EXPR_OP_MULT,
268 gnm_expr_new_binary
269 (gnm_expr_copy (expr_isnumber_1), GNM_EXPR_OP_MULT,
270 gnm_expr_new_funcall2
271 (fd_iferror,
272 gnm_expr_new_funcall3
273 (fd_if, gnm_expr_new_binary (gnm_expr_copy (expr_diff),
274 GNM_EXPR_OP_LT, make_cellref (0,-1)),
275 gnm_expr_new_constant (value_new_int (1)),
276 gnm_expr_new_constant (value_new_int (0))),
277 gnm_expr_new_constant (value_new_int (0))))));
278 expr_pos = gnm_expr_new_funcall1
279 (fd_sum,
280 gnm_expr_new_binary
281 (gnm_expr_copy (expr_isnumber_1), GNM_EXPR_OP_MULT,
282 gnm_expr_new_binary
283 (gnm_expr_copy (expr_isnumber_1), GNM_EXPR_OP_MULT,
284 gnm_expr_new_funcall2
285 (fd_iferror,
286 gnm_expr_new_funcall3
287 (fd_if, gnm_expr_new_binary (gnm_expr_copy (expr_diff),
288 GNM_EXPR_OP_GT, make_cellref (0,-1)),
289 gnm_expr_new_constant (value_new_int (1)),
290 gnm_expr_new_constant (value_new_int (0))),
291 gnm_expr_new_constant (value_new_int (0))))));
292 expr = gnm_expr_new_funcall2
293 (fd_min, expr_neg, expr_pos);
294 dao_set_cell_array_expr (dao, 1, 3, expr);
296 expr = gnm_expr_new_funcall1
297 (fd_sum, gnm_expr_new_binary
298 (expr_isnumber_1, GNM_EXPR_OP_MULT,
299 gnm_expr_new_binary
300 (expr_isnumber_2, GNM_EXPR_OP_MULT,
301 gnm_expr_new_funcall2
302 (fd_iferror, gnm_expr_new_funcall3
303 (fd_if, gnm_expr_new_binary (expr_diff,
304 GNM_EXPR_OP_NOT_EQUAL, make_cellref (0,-2)),
305 gnm_expr_new_constant (value_new_int (1)),
306 gnm_expr_new_constant (value_new_int (0))),
307 gnm_expr_new_constant (value_new_int (0))))));
308 dao_set_cell_array_expr (dao, 1, 4, expr);
310 expr = gnm_expr_new_funcall4 (fd_binomdist, make_cellref (0,-3), make_cellref (0,-2),
311 gnm_expr_new_constant (value_new_float (0.5)),
312 gnm_expr_new_constant (value_new_bool (TRUE)));
313 dao_set_cell_array_expr (dao, 1, 6,
314 gnm_expr_new_funcall2
315 (fd_min,
316 gnm_expr_copy (expr),
317 gnm_expr_new_binary
318 (gnm_expr_new_constant (value_new_int (1)),
319 GNM_EXPR_OP_SUB,
320 expr)));
322 expr = gnm_expr_new_binary (gnm_expr_new_constant (value_new_int (2)),
323 GNM_EXPR_OP_MULT, make_cellref (0,-1));
324 dao_set_cell_array_expr (dao, 1, 7, expr);
326 gnm_func_dec_usage (fd_median);
327 gnm_func_dec_usage (fd_if);
328 gnm_func_dec_usage (fd_min);
329 gnm_func_dec_usage (fd_sum);
330 gnm_func_dec_usage (fd_binomdist);
331 gnm_func_dec_usage (fd_isnumber);
332 gnm_func_dec_usage (fd_iferror);
334 value_release (val_1);
335 value_release (val_2);
337 dao_redraw_respan (dao);
339 return FALSE;
342 gboolean
343 analysis_tool_sign_test_engine (G_GNUC_UNUSED GOCmdContext *gcc, data_analysis_output_t *dao, gpointer specs,
344 analysis_tool_engine_t selector, gpointer result)
346 analysis_tools_data_sign_test_t *info = specs;
348 switch (selector) {
349 case TOOL_ENGINE_UPDATE_DESCRIPTOR:
350 return (dao_command_descriptor
351 (dao, _("Sign Test (%s)"), result)
352 == NULL);
353 case TOOL_ENGINE_UPDATE_DAO:
354 prepare_input_range (&info->base.input, info->base.group_by);
355 dao_adjust (dao, 1 + g_slist_length (info->base.input), 8);
356 return FALSE;
357 case TOOL_ENGINE_CLEAN_UP:
358 return analysis_tool_generic_clean (specs);
359 case TOOL_ENGINE_LAST_VALIDITY_CHECK:
360 return FALSE;
361 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
362 dao_prepare_output (NULL, dao, _("Sign Test"));
363 return FALSE;
364 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
365 return dao_format_output (dao, _("Sign Test"));
366 case TOOL_ENGINE_PERFORM_CALC:
367 default:
368 return analysis_tool_sign_test_engine_run (dao, specs);
370 return TRUE;
373 gboolean
374 analysis_tool_sign_test_two_engine (G_GNUC_UNUSED GOCmdContext *gcc, data_analysis_output_t *dao, gpointer specs,
375 analysis_tool_engine_t selector, gpointer result)
377 switch (selector) {
378 case TOOL_ENGINE_UPDATE_DESCRIPTOR:
379 return (dao_command_descriptor
380 (dao, _("Sign Test (%s)"), result)
381 == NULL);
382 case TOOL_ENGINE_UPDATE_DAO:
383 dao_adjust (dao, 3, 8);
384 return FALSE;
385 case TOOL_ENGINE_CLEAN_UP:
386 return analysis_tool_generic_b_clean (specs);
387 case TOOL_ENGINE_LAST_VALIDITY_CHECK:
388 return FALSE;
389 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
390 dao_prepare_output (NULL, dao, _("Sign Test"));
391 return FALSE;
392 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
393 return dao_format_output (dao, _("Sign Test"));
394 case TOOL_ENGINE_PERFORM_CALC:
395 default:
396 return analysis_tool_sign_test_two_engine_run (dao, specs);
398 return TRUE; /* We shouldn't get here */