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>
28 #include <tools/analysis-anova.h>
29 #include <tools/analysis-tools.h>
37 #include <style-border.h>
38 #include <style-color.h>
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
;
57 /* Check that at least two columns of data are given */
59 info
->err
= analysis_tools_too_few_cols
;
62 /* Check that at least two data rows of data are given */
64 info
->err
= analysis_tools_too_few_rows
;
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.
79 analysis_tool_anova_two_factor_no_rep_engine_run (data_analysis_output_t
*dao
,
80 analysis_tools_data_anova_two_factor_t
*info
)
83 GnmExpr
const *expr_check
;
84 GnmExpr
const *expr_region
;
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"
129 for (i
= 1; i
<= info
->n_r
; i
++, r
++) {
130 GnmExpr
const *expr_source
;
131 dao_set_italic (dao
, 0, r
, 0, r
);
133 GnmExpr
const *expr_label
;
134 expr_label
= gnm_expr_new_funcall3
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
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
)));
148 dao_set_cell_printf (dao
, 0, r
, _("Row %i"), i
);
149 expr_source
= gnm_expr_new_funcall4
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
));
168 for (i
= 1; i
<= info
->n_c
; i
++, r
++) {
169 GnmExpr
const *expr_source
;
170 dao_set_italic (dao
, 0, r
, 0, r
);
172 GnmExpr
const *expr_label
;
173 expr_label
= gnm_expr_new_funcall3
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
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)));
187 dao_set_cell_printf (dao
, 0, r
, _("Column %i"), i
);
188 expr_source
= gnm_expr_new_funcall5
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
));
208 dao_set_merge (dao
, 0, r
, 6, r
);
209 dao_set_italic (dao
, 0, r
, 6, r
);
212 expr_region
= gnm_expr_new_funcall5
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
)));
220 expr_region
= gnm_expr_new_constant (value_dup (info
->input
));
222 expr_check
= gnm_expr_new_funcall3
225 (gnm_expr_new_funcall1
226 (fd_count
, gnm_expr_copy (expr_region
)),
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
);
237 dao_set_italic (dao
, 0, r
, 0, r
+ 4);
238 set_cell_text_col (dao
, 0, r
, _("/Source of Variation"
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"
255 dao
->offset_col
+= 1;
256 dao
->offset_row
+= r
+ 1;
258 if (dao_cell_is_visible (dao
, 5, 2)) {
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
272 (gnm_expr_new_funcall1 (fd_sum
, gnm_expr_copy (expr_region
)),
274 gnm_expr_new_constant (value_new_int (2))),
276 gnm_expr_new_funcall1 (fd_count
, gnm_expr_copy (expr_region
)));
279 for (i
= 1; i
<= info
->n_r
; i
++) {
281 expr
= gnm_expr_new_funcall1
283 gnm_expr_new_funcall5
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
)));
299 for (i
= 1; i
<= info
->n_c
; i
++) {
301 expr
= gnm_expr_new_funcall1
303 gnm_expr_new_funcall5
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
326 (expr_t
, GNM_EXPR_OP_ADD
, expr_cf
),
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)));
354 gnm_expr_new_funcall3
356 make_cellref (-1, 0),
357 make_cellref (-3, 0),
358 make_cellref (-3, 2)));
361 gnm_expr_new_funcall3
363 make_cellref (-1, 0),
364 make_cellref (-3, 0),
365 make_cellref (-3, 1)));
368 gnm_expr_new_funcall3
370 gnm_expr_new_constant (value_new_float (info
->alpha
)),
371 make_cellref (-4, 0),
372 make_cellref (-4, 2)));
375 gnm_expr_new_funcall3
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
);
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
);
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.
415 analysis_tool_anova_two_factor_engine_run (data_analysis_output_t
*dao
,
416 analysis_tools_data_anova_two_factor_t
*info
)
420 GnmExpr
const *expr_check
;
421 GnmExpr
const *expr_source
;
422 GnmExpr
const *expr_total_count
;
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
++) {
464 GnmExpr
const *expr_label
;
465 expr_label
= gnm_expr_new_funcall3
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
);
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"));
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);
483 GnmExpr
const *expr_label
;
484 expr_label
= gnm_expr_new_funcall3
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
);
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"
497 for (k
= 1; k
<= info
->n_c
; k
++) {
498 expr_source
= gnm_expr_new_funcall5
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
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"
539 for (k
= 1; k
<= info
->n_c
; k
++) {
540 expr_source
= gnm_expr_new_funcall5
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
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
)));
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
584 (gnm_expr_copy (expr_total_count
),
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
);
595 dao_set_italic (dao
, 0, r
, 0, r
+ 5);
596 set_cell_text_col (dao
, 0, r
, _("/Source of Variation"
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"
614 dao
->offset_col
+= 1;
615 dao
->offset_row
+= r
+ 1;
617 if (dao_cell_is_visible (dao
, 5, 2)) {
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
632 (gnm_expr_new_funcall1 (fd_sum
, gnm_expr_copy (expr_source
)),
634 gnm_expr_new_constant (value_new_int (2))),
636 gnm_expr_copy (expr_total_count
));
639 for (i
= 1; i
<= info
->n_r
; i
++) {
641 int level_start
= (i
-1)*info
->replication
+ 1;
643 expr
= gnm_expr_new_funcall1
645 gnm_expr_new_funcall5
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
)));
661 for (k
= 1; k
<= info
->n_c
; k
++) {
663 expr
= gnm_expr_new_funcall1
665 gnm_expr_new_funcall5
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
)));
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
++) {
685 expr
= gnm_expr_new_funcall1
687 gnm_expr_new_funcall5
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
711 (gnm_expr_copy (expr_s
), GNM_EXPR_OP_ADD
, expr_cf
),
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)));
745 gnm_expr_new_funcall3
747 make_cellref (-1, 0),
748 make_cellref (-3, 0),
749 make_cellref (-3, 3)));
752 gnm_expr_new_funcall3
754 make_cellref (-1, 0),
755 make_cellref (-3, 0),
756 make_cellref (-3, 2)));
759 gnm_expr_new_funcall3
761 make_cellref (-1, 0),
762 make_cellref (-3, 0),
763 make_cellref (-3, 1)));
766 gnm_expr_new_funcall3
768 gnm_expr_new_constant (value_new_float (info
->alpha
)),
769 make_cellref (-4, 0),
770 make_cellref (-4, 3)));
773 gnm_expr_new_funcall3
775 gnm_expr_new_constant (value_new_float (info
->alpha
)),
776 make_cellref (-4, 0),
777 make_cellref (-4, 2)));
780 gnm_expr_new_funcall3
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
);
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
);
813 analysis_tool_anova_two_factor_engine_clean (G_GNUC_UNUSED data_analysis_output_t
*dao
,
816 analysis_tools_data_anova_two_factor_t
*info
= specs
;
818 value_release (info
->input
);
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
;
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
)
837 case TOOL_ENGINE_UPDATE_DAO
:
838 if (analysis_tool_anova_two_factor_prepare_input_range (info
))
840 if (info
->replication
== 1)
841 dao_adjust (dao
, 7, info
->n_c
+ info
->n_r
+ 12);
843 dao_adjust (dao
, MAX (2 + info
->n_c
, 7), info
->n_r
* 6 + 18);
845 case TOOL_ENGINE_CLEAN_UP
:
846 return analysis_tool_anova_two_factor_engine_clean (dao
, specs
);
847 case TOOL_ENGINE_LAST_VALIDITY_CHECK
:
849 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE
:
850 dao_prepare_output (NULL
, dao
, _("ANOVA"));
852 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE
:
853 return dao_format_output (dao
, _("Two Factor ANOVA"));
854 case TOOL_ENGINE_PERFORM_CALC
:
856 if (info
->replication
== 1)
857 return analysis_tool_anova_two_factor_no_rep_engine_run (dao
, info
);
859 return analysis_tool_anova_two_factor_engine_run (dao
, info
);
861 return TRUE
; /* We shouldn't get here */