1.12.42
[gnumeric.git] / src / tools / analysis-anova.c
blobb08ff56d6c9c6257fbba3d43a9084881aba402fe
1 /*
2 * analysis-anova.c:
5 * Author:
6 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
8 * (C) Copyright 2009 by Andreas J. Guelzow <aguelzow@pyrshep.ca>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses/>.
25 #include <gnumeric-config.h>
26 #include <glib/gi18n-lib.h>
27 #include <gnumeric.h>
28 #include <tools/analysis-anova.h>
29 #include <tools/analysis-tools.h>
30 #include <value.h>
31 #include <ranges.h>
32 #include <expr.h>
33 #include <func.h>
34 #include <sheet.h>
35 #include <numbers.h>
36 #include <mstyle.h>
37 #include <style-border.h>
38 #include <style-color.h>
41 static gboolean
42 analysis_tool_anova_two_factor_prepare_input_range (
43 analysis_tools_data_anova_two_factor_t *info)
45 info->rows = info->input->v_range.cell.b.row - info->input->v_range.cell.a.row +
46 (info->labels ? 0 : 1);
47 info->n_r = info->rows/info->replication;
48 info->n_c = info->input->v_range.cell.b.col - info->input->v_range.cell.a.col +
49 (info->labels ? 0 : 1);
51 /* Check that correct number of rows per sample */
52 if (info->rows % info->replication != 0) {
53 info->err = analysis_tools_replication_invalid;
54 return TRUE;
57 /* Check that at least two columns of data are given */
58 if (info->n_c < 2) {
59 info->err = analysis_tools_too_few_cols;
60 return TRUE;
62 /* Check that at least two data rows of data are given */
63 if (info->n_r < 2) {
64 info->err = analysis_tools_too_few_rows;
65 return TRUE;
68 return FALSE;
71 /************* ANOVA: Two-Factor Without Replication Tool ****************
73 * The results are given in a table which can be printed out in a new
74 * sheet, in a new workbook, or simply into an existing sheet.
76 **/
78 static gboolean
79 analysis_tool_anova_two_factor_no_rep_engine_run (data_analysis_output_t *dao,
80 analysis_tools_data_anova_two_factor_t *info)
82 int i, r;
83 GnmExpr const *expr_check;
84 GnmExpr const *expr_region;
86 GnmFunc *fd_index;
87 GnmFunc *fd_offset;
88 GnmFunc *fd_count;
89 GnmFunc *fd_sum;
90 GnmFunc *fd_sumsq;
91 GnmFunc *fd_average;
92 GnmFunc *fd_var;
93 GnmFunc *fd_if;
94 GnmFunc *fd_fdist;
95 GnmFunc *fd_finv;
97 fd_index = gnm_func_lookup_or_add_placeholder ("INDEX");
98 gnm_func_inc_usage (fd_index);
99 fd_offset = gnm_func_lookup_or_add_placeholder ("OFFSET");
100 gnm_func_inc_usage (fd_offset);
101 fd_count = gnm_func_lookup_or_add_placeholder ("COUNT");
102 gnm_func_inc_usage (fd_count);
103 fd_sum = gnm_func_lookup_or_add_placeholder ("SUM");
104 gnm_func_inc_usage (fd_sum);
105 fd_sumsq = gnm_func_lookup_or_add_placeholder ("SUMSQ");
106 gnm_func_inc_usage (fd_sumsq);
107 fd_average = gnm_func_lookup_or_add_placeholder ("AVERAGE");
108 gnm_func_inc_usage (fd_average);
109 fd_var = gnm_func_lookup_or_add_placeholder ("VAR");
110 gnm_func_inc_usage (fd_var);
111 fd_if = gnm_func_lookup_or_add_placeholder ("IF");
112 gnm_func_inc_usage (fd_if);
113 fd_fdist = gnm_func_lookup_or_add_placeholder ("FDIST");
114 gnm_func_inc_usage (fd_fdist);
115 fd_finv = gnm_func_lookup_or_add_placeholder ("FINV");
116 gnm_func_inc_usage (fd_finv);
118 dao_set_merge (dao, 0, 0, 4, 0);
119 dao_set_italic (dao, 0, 0, 0, 0);
120 dao_set_cell (dao, 0, 0, _("ANOVA: Two-Factor Without Replication"));
121 dao_set_italic (dao, 0, 2, 4, 2);
122 set_cell_text_row (dao, 0, 2, _("/Summary"
123 "/Count"
124 "/Sum"
125 "/Average"
126 "/Variance"));
127 r = 3;
129 for (i = 1; i <= info->n_r; i++, r++) {
130 GnmExpr const *expr_source;
131 dao_set_italic (dao, 0, r, 0, r);
132 if (info->labels) {
133 GnmExpr const *expr_label;
134 expr_label = gnm_expr_new_funcall3
135 (fd_index,
136 gnm_expr_new_constant (value_dup (info->input)),
137 gnm_expr_new_constant (value_new_int (i+1)),
138 gnm_expr_new_constant (value_new_int (1)));
139 dao_set_cell_expr (dao, 0, r, expr_label);
140 expr_source = gnm_expr_new_funcall5
141 (fd_offset,
142 gnm_expr_new_constant (value_dup (info->input)),
143 gnm_expr_new_constant (value_new_int (i)),
144 gnm_expr_new_constant (value_new_int (1)),
145 gnm_expr_new_constant (value_new_int (1)),
146 gnm_expr_new_constant (value_new_int (info->n_c)));
147 } else {
148 dao_set_cell_printf (dao, 0, r, _("Row %i"), i);
149 expr_source = gnm_expr_new_funcall4
150 (fd_offset,
151 gnm_expr_new_constant (value_dup (info->input)),
152 gnm_expr_new_constant (value_new_int (i-1)),
153 gnm_expr_new_constant (value_new_int (0)),
154 gnm_expr_new_constant (value_new_int (1)));
156 dao_set_cell_expr (dao, 1, r, gnm_expr_new_funcall1
157 (fd_count, gnm_expr_copy (expr_source)));
158 dao_set_cell_expr (dao, 2, r, gnm_expr_new_funcall1
159 (fd_sum, gnm_expr_copy (expr_source)));
160 dao_set_cell_expr (dao, 3, r, gnm_expr_new_funcall1
161 (fd_average, gnm_expr_copy (expr_source)));
162 dao_set_cell_expr (dao, 4, r, gnm_expr_new_funcall1
163 (fd_var, expr_source));
166 r++;
168 for (i = 1; i <= info->n_c; i++, r++) {
169 GnmExpr const *expr_source;
170 dao_set_italic (dao, 0, r, 0, r);
171 if (info->labels) {
172 GnmExpr const *expr_label;
173 expr_label = gnm_expr_new_funcall3
174 (fd_index,
175 gnm_expr_new_constant (value_dup (info->input)),
176 gnm_expr_new_constant (value_new_int (1)),
177 gnm_expr_new_constant (value_new_int (i+1)));
178 dao_set_cell_expr (dao, 0, r, expr_label);
179 expr_source = gnm_expr_new_funcall5
180 (fd_offset,
181 gnm_expr_new_constant (value_dup (info->input)),
182 gnm_expr_new_constant (value_new_int (1)),
183 gnm_expr_new_constant (value_new_int (i)),
184 gnm_expr_new_constant (value_new_int (info->n_r)),
185 gnm_expr_new_constant (value_new_int (1)));
186 } else {
187 dao_set_cell_printf (dao, 0, r, _("Column %i"), i);
188 expr_source = gnm_expr_new_funcall5
189 (fd_offset,
190 gnm_expr_new_constant (value_dup (info->input)),
191 gnm_expr_new_constant (value_new_int (0)),
192 gnm_expr_new_constant (value_new_int (i-1)),
193 gnm_expr_new_constant (value_new_int (info->n_r)),
194 gnm_expr_new_constant (value_new_int (1)));
196 dao_set_cell_expr (dao, 1, r, gnm_expr_new_funcall1
197 (fd_count, gnm_expr_copy (expr_source)));
198 dao_set_cell_expr (dao, 2, r, gnm_expr_new_funcall1
199 (fd_sum, gnm_expr_copy (expr_source)));
200 dao_set_cell_expr (dao, 3, r, gnm_expr_new_funcall1
201 (fd_average, gnm_expr_copy (expr_source)));
202 dao_set_cell_expr (dao, 4, r, gnm_expr_new_funcall1
203 (fd_var, expr_source));
206 r += 2;
208 dao_set_merge (dao, 0, r, 6, r);
209 dao_set_italic (dao, 0, r, 6, r);
211 if (info->labels)
212 expr_region = gnm_expr_new_funcall5
213 (fd_offset,
214 gnm_expr_new_constant (value_dup (info->input)),
215 gnm_expr_new_constant (value_new_int (1)),
216 gnm_expr_new_constant (value_new_int (1)),
217 gnm_expr_new_constant (value_new_int (info->n_r)),
218 gnm_expr_new_constant (value_new_int (info->n_c)));
219 else
220 expr_region = gnm_expr_new_constant (value_dup (info->input));
222 expr_check = gnm_expr_new_funcall3
223 (fd_if,
224 gnm_expr_new_binary
225 (gnm_expr_new_funcall1
226 (fd_count, gnm_expr_copy (expr_region)),
227 GNM_EXPR_OP_EQUAL,
228 gnm_expr_new_constant (value_new_int (info->n_r*info->n_c))),
229 gnm_expr_new_constant (value_new_int (1)),
230 gnm_expr_new_constant (value_new_int (-1)));
231 dao_set_cell_expr (dao, 0, r, expr_check);
232 dao_set_format (dao, 0, r, 0, r,
233 _("\"ANOVA\";[Red]\"Invalid ANOVA: Missing Observations\""));
234 dao_set_align (dao, 0, r, 0, r, GNM_HALIGN_LEFT, GNM_VALIGN_BOTTOM);
236 r++;
237 dao_set_italic (dao, 0, r, 0, r + 4);
238 set_cell_text_col (dao, 0, r, _("/Source of Variation"
239 "/Rows"
240 "/Columns"
241 "/Error"
242 "/Total"));
243 dao_set_italic (dao, 1, r, 6, r);
244 dao_set_border (dao, 0, r, 6, r, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THIN,
245 style_color_black (), GNM_STYLE_BORDER_HORIZONTAL);
246 dao_set_border (dao, 0, r+3, 6, r+3, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THIN,
247 style_color_black (), GNM_STYLE_BORDER_HORIZONTAL);
248 set_cell_text_row (dao, 1, r, _("/SS"
249 "/df"
250 "/MS"
251 "/F"
252 "/P-value"
253 "/F critical"));
255 dao->offset_col += 1;
256 dao->offset_row += r + 1;
258 if (dao_cell_is_visible (dao, 5, 2)) {
259 char *cc;
260 GnmExprList *args;
262 GnmExpr const *expr_ms;
263 GnmExpr const *expr_total;
264 GnmExpr const *expr_a;
265 GnmExpr const *expr_b;
266 GnmExpr const *expr_t;
267 GnmExpr const *expr_cf;
269 expr_t = gnm_expr_new_funcall1 (fd_sumsq, gnm_expr_copy (expr_region));
270 expr_cf = gnm_expr_new_binary
271 (gnm_expr_new_binary
272 (gnm_expr_new_funcall1 (fd_sum, gnm_expr_copy (expr_region)),
273 GNM_EXPR_OP_EXP,
274 gnm_expr_new_constant (value_new_int (2))),
275 GNM_EXPR_OP_DIV,
276 gnm_expr_new_funcall1 (fd_count, gnm_expr_copy (expr_region)));
278 args = NULL;
279 for (i = 1; i <= info->n_r; i++) {
280 GnmExpr const *expr;
281 expr = gnm_expr_new_funcall1
282 (fd_sum,
283 gnm_expr_new_funcall5
284 (fd_offset,
285 gnm_expr_new_constant (value_dup (info->input)),
286 gnm_expr_new_constant (value_new_int
287 ((info->labels)?i:(i-1))),
288 gnm_expr_new_constant (value_new_int
289 ((info->labels)?1:0)),
290 gnm_expr_new_constant (value_new_int (1)),
291 gnm_expr_new_constant (value_new_int (info->n_c))));
292 args = gnm_expr_list_prepend (args, expr);
294 expr_a = gnm_expr_new_binary
295 (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
296 gnm_expr_new_constant (value_new_int (info->n_c)));
298 args = NULL;
299 for (i = 1; i <= info->n_c; i++) {
300 GnmExpr const *expr;
301 expr = gnm_expr_new_funcall1
302 (fd_sum,
303 gnm_expr_new_funcall5
304 (fd_offset,
305 gnm_expr_new_constant (value_dup (info->input)),
306 gnm_expr_new_constant (value_new_int
307 ((info->labels)?1:0)),
308 gnm_expr_new_constant (value_new_int
309 ((info->labels)?i:(i-1))),
310 gnm_expr_new_constant (value_new_int (info->n_r)),
311 gnm_expr_new_constant (value_new_int (1))));
312 args = gnm_expr_list_prepend (args, expr);
314 expr_b = gnm_expr_new_binary
315 (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
316 gnm_expr_new_constant (value_new_int (info->n_r)));
318 dao_set_cell_expr (dao, 0, 0, gnm_expr_new_binary
319 (gnm_expr_copy (expr_a), GNM_EXPR_OP_SUB,
320 gnm_expr_copy (expr_cf)));
321 dao_set_cell_expr (dao, 0, 1, gnm_expr_new_binary
322 (gnm_expr_copy (expr_b), GNM_EXPR_OP_SUB,
323 gnm_expr_copy (expr_cf)));
324 dao_set_cell_expr (dao, 0, 2, gnm_expr_new_binary
325 (gnm_expr_new_binary
326 (expr_t, GNM_EXPR_OP_ADD, expr_cf),
327 GNM_EXPR_OP_SUB ,
328 gnm_expr_new_binary
329 (expr_a, GNM_EXPR_OP_ADD, expr_b)));
330 expr_total = gnm_expr_new_funcall1
331 (fd_sum, make_rangeref (0, -3, 0, -1));
332 dao_set_cell_expr (dao, 0, 3, gnm_expr_copy (expr_total));
333 dao_set_cell_int (dao, 1, 0, info->n_r - 1);
334 dao_set_cell_int (dao, 1, 1, info->n_c - 1);
335 dao_set_cell_expr (dao, 1, 2, gnm_expr_new_binary
336 (make_cellref (0,-1), GNM_EXPR_OP_MULT,
337 make_cellref (0,-2)));
338 dao_set_cell_expr (dao, 1, 3, expr_total);
340 expr_ms = gnm_expr_new_binary (make_cellref (-2,0), GNM_EXPR_OP_DIV,
341 make_cellref (-1,0));
342 dao_set_cell_expr (dao, 2, 0, gnm_expr_copy (expr_ms));
343 dao_set_cell_expr (dao, 2, 1, gnm_expr_copy (expr_ms));
344 dao_set_cell_expr (dao, 2, 2, expr_ms);
346 dao_set_cell_expr (dao, 3, 0, gnm_expr_new_binary
347 (make_cellref (-1,0), GNM_EXPR_OP_DIV,
348 make_cellref (-1,2)));
349 dao_set_cell_expr (dao, 3, 1, gnm_expr_new_binary
350 (make_cellref (-1,0), GNM_EXPR_OP_DIV,
351 make_cellref (-1,1)));
352 dao_set_cell_expr
353 (dao, 4, 0,
354 gnm_expr_new_funcall3
355 (fd_fdist,
356 make_cellref (-1, 0),
357 make_cellref (-3, 0),
358 make_cellref (-3, 2)));
359 dao_set_cell_expr
360 (dao, 4, 1,
361 gnm_expr_new_funcall3
362 (fd_fdist,
363 make_cellref (-1, 0),
364 make_cellref (-3, 0),
365 make_cellref (-3, 1)));
366 dao_set_cell_expr
367 (dao, 5, 0,
368 gnm_expr_new_funcall3
369 (fd_finv,
370 gnm_expr_new_constant (value_new_float (info->alpha)),
371 make_cellref (-4, 0),
372 make_cellref (-4, 2)));
373 dao_set_cell_expr
374 (dao, 5, 1,
375 gnm_expr_new_funcall3
376 (fd_finv,
377 gnm_expr_new_constant (value_new_float (info->alpha)),
378 make_cellref (-4, 0),
379 make_cellref (-4, 1)));
380 cc = g_strdup_printf ("%s = %.2" GNM_FORMAT_f, "\xce\xb1", info->alpha);
381 dao_set_cell_comment (dao, 5, 0, cc);
382 dao_set_cell_comment (dao, 5, 1, cc);
383 g_free (cc);
384 } else
385 dao_set_cell (dao, 0, 0, _("Insufficient space available for ANOVA table."));
387 gnm_func_dec_usage (fd_index);
388 gnm_func_dec_usage (fd_count);
389 gnm_func_dec_usage (fd_offset);
390 gnm_func_dec_usage (fd_sum);
391 gnm_func_dec_usage (fd_sumsq);
392 gnm_func_dec_usage (fd_average);
393 gnm_func_dec_usage (fd_var);
394 gnm_func_dec_usage (fd_if);
395 gnm_func_dec_usage (fd_finv);
396 gnm_func_dec_usage (fd_fdist);
398 gnm_expr_free (expr_region);
400 dao_redraw_respan (dao);
402 return FALSE;
406 /************* ANOVA: Two-Factor With Replication Tool *******************
408 * The results are given in a table which can be printed out in a new
409 * sheet, in a new workbook, or simply into an existing sheet.
414 static gboolean
415 analysis_tool_anova_two_factor_engine_run (data_analysis_output_t *dao,
416 analysis_tools_data_anova_two_factor_t *info)
419 int i, k, r;
420 GnmExpr const *expr_check;
421 GnmExpr const *expr_source;
422 GnmExpr const *expr_total_count;
424 GnmFunc *fd_index;
425 GnmFunc *fd_offset;
426 GnmFunc *fd_count;
427 GnmFunc *fd_sum;
428 GnmFunc *fd_sumsq;
429 GnmFunc *fd_average;
430 GnmFunc *fd_var;
431 GnmFunc *fd_if;
432 GnmFunc *fd_fdist;
433 GnmFunc *fd_finv;
435 fd_index = gnm_func_lookup_or_add_placeholder ("INDEX");
436 gnm_func_inc_usage (fd_index);
437 fd_offset = gnm_func_lookup_or_add_placeholder ("OFFSET");
438 gnm_func_inc_usage (fd_offset);
439 fd_count = gnm_func_lookup_or_add_placeholder ("COUNT");
440 gnm_func_inc_usage (fd_count);
441 fd_sum = gnm_func_lookup_or_add_placeholder ("SUM");
442 gnm_func_inc_usage (fd_sum);
443 fd_sumsq = gnm_func_lookup_or_add_placeholder ("SUMSQ");
444 gnm_func_inc_usage (fd_sumsq);
445 fd_average = gnm_func_lookup_or_add_placeholder ("AVERAGE");
446 gnm_func_inc_usage (fd_average);
447 fd_var = gnm_func_lookup_or_add_placeholder ("VAR");
448 gnm_func_inc_usage (fd_var);
449 fd_if = gnm_func_lookup_or_add_placeholder ("IF");
450 gnm_func_inc_usage (fd_if);
451 fd_fdist = gnm_func_lookup_or_add_placeholder ("FDIST");
452 gnm_func_inc_usage (fd_fdist);
453 fd_finv = gnm_func_lookup_or_add_placeholder ("FINV");
454 gnm_func_inc_usage (fd_finv);
456 dao_set_merge (dao, 0, 0, 4, 0);
457 dao_set_italic (dao, 0, 0, 0, 0);
458 dao_set_cell (dao, 0, 0, _("ANOVA: Two-Factor Fixed Effects With Replication"));
459 dao_set_italic (dao, 0, 2, info->n_c + 1, 2);
460 dao_set_cell (dao, 0, 2, _("Summary"));
462 for (k = 1; k <= info->n_c; k++) {
463 if (info->labels) {
464 GnmExpr const *expr_label;
465 expr_label = gnm_expr_new_funcall3
466 (fd_index,
467 gnm_expr_new_constant (value_dup (info->input)),
468 gnm_expr_new_constant (value_new_int (1)),
469 gnm_expr_new_constant (value_new_int (k+1)));
470 dao_set_cell_expr (dao, k, 2, expr_label);
471 } else
472 /*xgettext: this is a label for the first, second,... level of factor B in an ANOVA*/
473 dao_set_cell_printf (dao, k, 2, _("B, Level %i"), k);
475 dao_set_cell (dao, info->n_c + 1, 2, _("Subtotal"));
477 r = 3;
478 for (i = 1; i <= info->n_r; i++, r += 6) {
479 int level_start = (i-1)*info->replication + ((info->labels) ? 1 : 0);
481 dao_set_italic (dao, 0, r, 0, r+4);
482 if (info->labels) {
483 GnmExpr const *expr_label;
484 expr_label = gnm_expr_new_funcall3
485 (fd_index,
486 gnm_expr_new_constant (value_dup (info->input)),
487 gnm_expr_new_constant (value_new_int (level_start + 1)),
488 gnm_expr_new_constant (value_new_int (1)));
489 dao_set_cell_expr (dao, 0, r, expr_label);
490 } else
491 /*xgettext: this is a label for the first, second,... level of factor A in an ANOVA*/
492 dao_set_cell_printf (dao, 0, r, _("A, Level %i"), i);
493 set_cell_text_col (dao, 0, r + 1, _("/Count"
494 "/Sum"
495 "/Average"
496 "/Variance"));
497 for (k = 1; k <= info->n_c; k++) {
498 expr_source = gnm_expr_new_funcall5
499 (fd_offset,
500 gnm_expr_new_constant (value_dup (info->input)),
501 gnm_expr_new_constant (value_new_int (level_start)),
502 gnm_expr_new_constant (value_new_int ((info->labels) ? k : (k - 1))),
503 gnm_expr_new_constant (value_new_int (info->replication)),
504 gnm_expr_new_constant (value_new_int (1)));
505 dao_set_cell_expr (dao, k, r + 1, gnm_expr_new_funcall1
506 (fd_count, gnm_expr_copy (expr_source)));
507 dao_set_cell_expr (dao, k, r + 2, gnm_expr_new_funcall1
508 (fd_sum, gnm_expr_copy (expr_source)));
509 dao_set_cell_expr (dao, k, r + 3, gnm_expr_new_funcall1
510 (fd_average, gnm_expr_copy (expr_source)));
511 dao_set_cell_expr (dao, k, r + 4, gnm_expr_new_funcall1
512 (fd_var, expr_source));
515 expr_source = gnm_expr_new_funcall5
516 (fd_offset,
517 gnm_expr_new_constant (value_dup (info->input)),
518 gnm_expr_new_constant (value_new_int (level_start)),
519 gnm_expr_new_constant (value_new_int ((info->labels) ? 1 : 0)),
520 gnm_expr_new_constant (value_new_int (info->replication)),
521 gnm_expr_new_constant (value_new_int (info->n_c)));
522 dao_set_cell_expr (dao, k, r + 1, gnm_expr_new_funcall1
523 (fd_count, gnm_expr_copy (expr_source)));
524 dao_set_cell_expr (dao, k, r + 2, gnm_expr_new_funcall1
525 (fd_sum, gnm_expr_copy (expr_source)));
526 dao_set_cell_expr (dao, k, r + 3, gnm_expr_new_funcall1
527 (fd_average, gnm_expr_copy (expr_source)));
528 dao_set_cell_expr (dao, k, r + 4, gnm_expr_new_funcall1
529 (fd_var, expr_source));
532 dao_set_italic (dao, 0, r, 0, r+4);
533 dao_set_cell (dao, 0, r, _("Subtotal"));
534 set_cell_text_col (dao, 0, r + 1, _("/Count"
535 "/Sum"
536 "/Average"
537 "/Variance"));
539 for (k = 1; k <= info->n_c; k++) {
540 expr_source = gnm_expr_new_funcall5
541 (fd_offset,
542 gnm_expr_new_constant (value_dup (info->input)),
543 gnm_expr_new_constant (value_new_int ((info->labels) ? 1 : 0)),
544 gnm_expr_new_constant (value_new_int ((info->labels) ? k : (k - 1))),
545 gnm_expr_new_constant (value_new_int (info->replication * info->n_r)),
546 gnm_expr_new_constant (value_new_int (1)));
547 dao_set_cell_expr (dao, k, r + 1, gnm_expr_new_funcall1
548 (fd_count, gnm_expr_copy (expr_source)));
549 dao_set_cell_expr (dao, k, r + 2, gnm_expr_new_funcall1
550 (fd_sum, gnm_expr_copy (expr_source)));
551 dao_set_cell_expr (dao, k, r + 3, gnm_expr_new_funcall1
552 (fd_average, gnm_expr_copy (expr_source)));
553 dao_set_cell_expr (dao, k, r + 4, gnm_expr_new_funcall1
554 (fd_var, expr_source));
557 dao_set_italic (dao, info->n_c + 1, r, info->n_c + 1, r);
558 dao_set_cell (dao, info->n_c + 1, r, _("Total"));
560 expr_source = gnm_expr_new_funcall5
561 (fd_offset,
562 gnm_expr_new_constant (value_dup (info->input)),
563 gnm_expr_new_constant (value_new_int ((info->labels) ? 1 : 0)),
564 gnm_expr_new_constant (value_new_int ((info->labels) ? 1 : 0)),
565 gnm_expr_new_constant (value_new_int (info->replication * info->n_r)),
566 gnm_expr_new_constant (value_new_int (info->n_c)));
567 expr_total_count = gnm_expr_new_funcall1 (fd_count, gnm_expr_copy (expr_source));
568 dao_set_cell_expr (dao, info->n_c + 1, r + 1, gnm_expr_copy (expr_total_count));
569 dao_set_cell_expr (dao, info->n_c + 1, r + 2, gnm_expr_new_funcall1
570 (fd_sum, gnm_expr_copy (expr_source)));
571 dao_set_cell_expr (dao, info->n_c + 1, r + 3, gnm_expr_new_funcall1
572 (fd_average, gnm_expr_copy (expr_source)));
573 dao_set_cell_expr (dao, info->n_c + 1, r + 4, gnm_expr_new_funcall1
574 (fd_var, gnm_expr_copy (expr_source)));
576 r += 7;
578 dao_set_merge (dao, 0, r, 6, r);
579 dao_set_italic (dao, 0, r, 6, r);
581 expr_check = gnm_expr_new_funcall3
582 (fd_if,
583 gnm_expr_new_binary
584 (gnm_expr_copy (expr_total_count),
585 GNM_EXPR_OP_EQUAL,
586 gnm_expr_new_constant (value_new_int (info->n_r*info->n_c*info->replication))),
587 gnm_expr_new_constant (value_new_int (1)),
588 gnm_expr_new_constant (value_new_int (-1)));
589 dao_set_cell_expr (dao, 0, r, expr_check);
590 dao_set_format (dao, 0, r, 0, r,
591 _("\"ANOVA\";[Red]\"Invalid ANOVA: Missing Observations\""));
592 dao_set_align (dao, 0, r, 0, r, GNM_HALIGN_LEFT, GNM_VALIGN_BOTTOM);
594 r++;
595 dao_set_italic (dao, 0, r, 0, r + 5);
596 set_cell_text_col (dao, 0, r, _("/Source of Variation"
597 "/Factor A"
598 "/Factor B"
599 "/Interaction"
600 "/Error"
601 "/Total"));
602 dao_set_italic (dao, 1, r, 6, r);
603 dao_set_border (dao, 0, r, 6, r, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THIN,
604 style_color_black (), GNM_STYLE_BORDER_HORIZONTAL);
605 dao_set_border (dao, 0, r+4, 6, r+4, MSTYLE_BORDER_BOTTOM, GNM_STYLE_BORDER_THIN,
606 style_color_black (), GNM_STYLE_BORDER_HORIZONTAL);
607 set_cell_text_row (dao, 1, r, _("/SS"
608 "/df"
609 "/MS"
610 "/F"
611 "/P-value"
612 "/F critical"));
614 dao->offset_col += 1;
615 dao->offset_row += r + 1;
617 if (dao_cell_is_visible (dao, 5, 2)) {
618 char *cc;
619 GnmExprList *args;
621 GnmExpr const *expr_ms;
622 GnmExpr const *expr_total;
623 GnmExpr const *expr_a;
624 GnmExpr const *expr_b;
625 GnmExpr const *expr_t;
626 GnmExpr const *expr_s;
627 GnmExpr const *expr_cf;
629 expr_t = gnm_expr_new_funcall1 (fd_sumsq, gnm_expr_copy (expr_source));
630 expr_cf = gnm_expr_new_binary
631 (gnm_expr_new_binary
632 (gnm_expr_new_funcall1 (fd_sum, gnm_expr_copy (expr_source)),
633 GNM_EXPR_OP_EXP,
634 gnm_expr_new_constant (value_new_int (2))),
635 GNM_EXPR_OP_DIV,
636 gnm_expr_copy (expr_total_count));
638 args = NULL;
639 for (i = 1; i <= info->n_r; i++) {
640 GnmExpr const *expr;
641 int level_start = (i-1)*info->replication + 1;
643 expr = gnm_expr_new_funcall1
644 (fd_sum,
645 gnm_expr_new_funcall5
646 (fd_offset,
647 gnm_expr_new_constant (value_dup (info->input)),
648 gnm_expr_new_constant (value_new_int
649 ((info->labels)?level_start:(level_start-1))),
650 gnm_expr_new_constant (value_new_int
651 ((info->labels)?1:0)),
652 gnm_expr_new_constant (value_new_int (info->replication)),
653 gnm_expr_new_constant (value_new_int (info->n_c))));
654 args = gnm_expr_list_prepend (args, expr);
656 expr_a = gnm_expr_new_binary
657 (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
658 gnm_expr_new_constant (value_new_int (info->n_c * info->replication)));
660 args = NULL;
661 for (k = 1; k <= info->n_c; k++) {
662 GnmExpr const *expr;
663 expr = gnm_expr_new_funcall1
664 (fd_sum,
665 gnm_expr_new_funcall5
666 (fd_offset,
667 gnm_expr_new_constant (value_dup (info->input)),
668 gnm_expr_new_constant (value_new_int
669 ((info->labels)?1:0)),
670 gnm_expr_new_constant (value_new_int
671 ((info->labels)?k:(k-1))),
672 gnm_expr_new_constant (value_new_int (info->n_r * info->replication)),
673 gnm_expr_new_constant (value_new_int (1))));
674 args = gnm_expr_list_prepend (args, expr);
676 expr_b = gnm_expr_new_binary
677 (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
678 gnm_expr_new_constant (value_new_int (info->n_r * info->replication)));
680 args = NULL;
681 for (i = 1; i <= info->n_r; i++) {
682 int level_start = (i-1)*info->replication + 1;
683 for (k = 1; k <= info->n_c; k++) {
684 GnmExpr const *expr;
685 expr = gnm_expr_new_funcall1
686 (fd_sum,
687 gnm_expr_new_funcall5
688 (fd_offset,
689 gnm_expr_new_constant (value_dup (info->input)),
690 gnm_expr_new_constant
691 (value_new_int ((info->labels)?level_start:level_start-1)),
692 gnm_expr_new_constant (value_new_int
693 ((info->labels)?k:(k-1))),
694 gnm_expr_new_constant (value_new_int (info->replication)),
695 gnm_expr_new_constant (value_new_int (1))));
696 args = gnm_expr_list_prepend (args, expr);
699 expr_s = gnm_expr_new_binary
700 (gnm_expr_new_funcall (fd_sumsq, args), GNM_EXPR_OP_DIV,
701 gnm_expr_new_constant (value_new_int (info->replication)));
703 dao_set_cell_expr (dao, 0, 0, gnm_expr_new_binary
704 (gnm_expr_copy (expr_a), GNM_EXPR_OP_SUB,
705 gnm_expr_copy (expr_cf)));
706 dao_set_cell_expr (dao, 0, 1, gnm_expr_new_binary
707 (gnm_expr_copy (expr_b), GNM_EXPR_OP_SUB,
708 gnm_expr_copy (expr_cf)));
709 dao_set_cell_expr (dao, 0, 2, gnm_expr_new_binary
710 (gnm_expr_new_binary
711 (gnm_expr_copy (expr_s), GNM_EXPR_OP_ADD, expr_cf),
712 GNM_EXPR_OP_SUB ,
713 gnm_expr_new_binary
714 (expr_a, GNM_EXPR_OP_ADD, expr_b)));
715 dao_set_cell_expr (dao, 0, 3, gnm_expr_new_binary (expr_t, GNM_EXPR_OP_SUB, expr_s));
716 expr_total = gnm_expr_new_funcall1
717 (fd_sum, make_rangeref (0, -4, 0, -1));
718 dao_set_cell_expr (dao, 0, 4, gnm_expr_copy (expr_total));
719 dao_set_cell_int (dao, 1, 0, info->n_r - 1);
720 dao_set_cell_int (dao, 1, 1, info->n_c - 1);
721 dao_set_cell_expr (dao, 1, 2, gnm_expr_new_binary
722 (make_cellref (0,-1), GNM_EXPR_OP_MULT,
723 make_cellref (0,-2)));
724 dao_set_cell_int (dao, 1, 3, info->n_c*info->n_r*(info->replication - 1));
725 dao_set_cell_expr (dao, 1, 4, expr_total);
727 expr_ms = gnm_expr_new_binary (make_cellref (-2,0), GNM_EXPR_OP_DIV,
728 make_cellref (-1,0));
729 dao_set_cell_expr (dao, 2, 0, gnm_expr_copy (expr_ms));
730 dao_set_cell_expr (dao, 2, 1, gnm_expr_copy (expr_ms));
731 dao_set_cell_expr (dao, 2, 2, gnm_expr_copy (expr_ms));
732 dao_set_cell_expr (dao, 2, 3, expr_ms);
734 dao_set_cell_expr (dao, 3, 0, gnm_expr_new_binary
735 (make_cellref (-1,0), GNM_EXPR_OP_DIV,
736 make_cellref (-1,3)));
737 dao_set_cell_expr (dao, 3, 1, gnm_expr_new_binary
738 (make_cellref (-1,0), GNM_EXPR_OP_DIV,
739 make_cellref (-1,2)));
740 dao_set_cell_expr (dao, 3, 2, gnm_expr_new_binary
741 (make_cellref (-1,0), GNM_EXPR_OP_DIV,
742 make_cellref (-1,1)));
743 dao_set_cell_expr
744 (dao, 4, 0,
745 gnm_expr_new_funcall3
746 (fd_fdist,
747 make_cellref (-1, 0),
748 make_cellref (-3, 0),
749 make_cellref (-3, 3)));
750 dao_set_cell_expr
751 (dao, 4, 1,
752 gnm_expr_new_funcall3
753 (fd_fdist,
754 make_cellref (-1, 0),
755 make_cellref (-3, 0),
756 make_cellref (-3, 2)));
757 dao_set_cell_expr
758 (dao, 4, 2,
759 gnm_expr_new_funcall3
760 (fd_fdist,
761 make_cellref (-1, 0),
762 make_cellref (-3, 0),
763 make_cellref (-3, 1)));
764 dao_set_cell_expr
765 (dao, 5, 0,
766 gnm_expr_new_funcall3
767 (fd_finv,
768 gnm_expr_new_constant (value_new_float (info->alpha)),
769 make_cellref (-4, 0),
770 make_cellref (-4, 3)));
771 dao_set_cell_expr
772 (dao, 5, 1,
773 gnm_expr_new_funcall3
774 (fd_finv,
775 gnm_expr_new_constant (value_new_float (info->alpha)),
776 make_cellref (-4, 0),
777 make_cellref (-4, 2)));
778 dao_set_cell_expr
779 (dao, 5, 2,
780 gnm_expr_new_funcall3
781 (fd_finv,
782 gnm_expr_new_constant (value_new_float (info->alpha)),
783 make_cellref (-4, 0),
784 make_cellref (-4, 1)));
785 cc = g_strdup_printf ("%s = %.2" GNM_FORMAT_f, "\xce\xb1", info->alpha);
786 dao_set_cell_comment (dao, 5, 0, cc);
787 dao_set_cell_comment (dao, 5, 1, cc);
788 dao_set_cell_comment (dao, 5, 2, cc);
789 g_free (cc);
790 } else
791 dao_set_cell (dao, 0, 0, _("Insufficient space available for ANOVA table."));
793 gnm_func_dec_usage (fd_index);
794 gnm_func_dec_usage (fd_count);
795 gnm_func_dec_usage (fd_offset);
796 gnm_func_dec_usage (fd_sum);
797 gnm_func_dec_usage (fd_sumsq);
798 gnm_func_dec_usage (fd_average);
799 gnm_func_dec_usage (fd_var);
800 gnm_func_dec_usage (fd_if);
801 gnm_func_dec_usage (fd_finv);
802 gnm_func_dec_usage (fd_fdist);
804 gnm_expr_free (expr_source);
805 gnm_expr_free (expr_total_count);
807 dao_redraw_respan (dao);
809 return FALSE;
812 static gboolean
813 analysis_tool_anova_two_factor_engine_clean (G_GNUC_UNUSED data_analysis_output_t *dao,
814 gpointer specs)
816 analysis_tools_data_anova_two_factor_t *info = specs;
818 value_release (info->input);
819 info->input = NULL;
821 return FALSE;
824 gboolean
825 analysis_tool_anova_two_factor_engine (G_GNUC_UNUSED GOCmdContext *gcc, data_analysis_output_t *dao, gpointer specs,
826 analysis_tool_engine_t selector, gpointer result)
828 analysis_tools_data_anova_two_factor_t *info = specs;
830 switch (selector) {
831 case TOOL_ENGINE_UPDATE_DESCRIPTOR:
832 return (dao_command_descriptor (
833 dao, (info->replication == 1) ?
834 _("Two Factor ANOVA (%s), no replication") :
835 _("Two Factor ANOVA (%s), with replication") , result)
836 == NULL);
837 case TOOL_ENGINE_UPDATE_DAO:
838 if (analysis_tool_anova_two_factor_prepare_input_range (info))
839 return TRUE;
840 if (info->replication == 1)
841 dao_adjust (dao, 7, info->n_c + info->n_r + 12);
842 else
843 dao_adjust (dao, MAX (2 + info->n_c, 7), info->n_r * 6 + 18);
844 return FALSE;
845 case TOOL_ENGINE_CLEAN_UP:
846 return analysis_tool_anova_two_factor_engine_clean (dao, specs);
847 case TOOL_ENGINE_LAST_VALIDITY_CHECK:
848 return FALSE;
849 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
850 dao_prepare_output (NULL, dao, _("ANOVA"));
851 return FALSE;
852 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
853 return dao_format_output (dao, _("Two Factor ANOVA"));
854 case TOOL_ENGINE_PERFORM_CALC:
855 default:
856 if (info->replication == 1)
857 return analysis_tool_anova_two_factor_no_rep_engine_run (dao, info);
858 else
859 return analysis_tool_anova_two_factor_engine_run (dao, info);
861 return TRUE; /* We shouldn't get here */