/* PSPP - a program for statistical analysis.
-- Copyright (C) 2009 Free Software Foundation, Inc.
++ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <libpspp/misc.h>
#include <libpspp/message.h>
-#include <output/table.h>
+#include <output/tab.h>
+#include <output/charts/scree.h>
+#include <output/chart-item.h>
#include "gettext.h"
#define _(msgid) gettext (msgid)
EXTRACTION_PAF,
};
+enum plot_opts
+ {
+ PLOT_SCREE = 0x0001,
+ PLOT_ROTATION = 0x0002
+ };
+
enum print_opts
{
PRINT_UNIVARIATE = 0x0001,
enum mv_class exclude;
enum print_opts print;
enum extraction_method extraction;
+ enum plot_opts plot;
/* Extraction Criteria */
int n_factors;
factor.econverge = 0.001;
factor.blank = 0;
factor.sort = false;
+ factor.plot = 0;
factor.wv = dict_get_weight (dict);
PV_NO_DUPLICATE | PV_NUMERIC))
goto error;
+ if (factor.n_vars < 2)
+ msg (MW, _("Factor analysis on a single variable is not useful."));
+
while (lex_token (lexer) != '.')
{
lex_match (lexer, '/');
-
if (lex_match_id (lexer, "PLOT"))
{
lex_match (lexer, '=');
{
if (lex_match_id (lexer, "EIGEN"))
{
+ factor.plot |= PLOT_SCREE;
}
#if FACTOR_FULLY_IMPLEMENTED
else if (lex_match_id (lexer, "ROTATION"))
}
+static void
+show_scree (const struct cmd_factor *f, struct idata *idata)
+{
+ struct scree *s;
+ const char *label ;
+
+ if ( !(f->plot & PLOT_SCREE) )
+ return;
+
+
+ label = f->extraction == EXTRACTION_PC ? _("Component Number") : _("Factor Number");
+
+ s = scree_create (idata->eval, label);
+
+ scree_submit (s);
+}
static void
show_communalities (const struct cmd_factor * factor,
if (nc <= 1)
return;
- t = tab_create (nc, nr, 0);
+ t = tab_create (nc, nr);
tab_title (t, _("Communalities"));
- tab_dim (t, tab_natural_dimensions, NULL);
-
tab_headers (t, heading_columns, 0, heading_rows, 0);
c = 1;
show_factor_matrix (const struct cmd_factor *factor, struct idata *idata, const gsl_matrix *fm)
{
int i;
- const int n_factors = n_extracted_factors (factor, idata);
+ const int n_factors = idata->n_extractions;
const int heading_columns = 1;
const int heading_rows = 2;
const int nc = heading_columns + n_factors;
gsl_permutation *perm;
- struct tab_table *t = tab_create (nc, nr, 0);
+ struct tab_table *t = tab_create (nc, nr);
if ( factor->extraction == EXTRACTION_PC )
tab_title (t, _("Component Matrix"));
else
tab_title (t, _("Factor Matrix"));
- tab_dim (t, tab_natural_dimensions, NULL);
-
tab_headers (t, heading_columns, 0, heading_rows, 0);
if ( factor->extraction == EXTRACTION_PC )
if ( nc <= heading_columns)
return;
- t = tab_create (nc, nr, 0);
+ t = tab_create (nc, nr);
tab_title (t, _("Total Variance Explained"));
- tab_dim (t, tab_natural_dimensions, NULL);
-
tab_headers (t, heading_columns, 0, heading_rows, 0);
/* Outline the box */
if (factor->print & PRINT_EXTRACTION)
{
- if ( i < n_extracted_factors (factor, idata))
+ if (i < idata->n_extractions)
{
/* Sums of squared loadings */
tab_double (t, c++, i + heading_rows, 0, e_lambda, NULL);
if (nr <= heading_rows && suffix_rows == 0)
return;
- t = tab_create (nc, nr + suffix_rows, 0);
+ t = tab_create (nc, nr + suffix_rows);
tab_title (t, _("Correlation Matrix"));
- tab_dim (t, tab_natural_dimensions, NULL);
-
tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
if (nr > heading_rows)
const int nr = heading_rows + factor->n_vars;
- struct tab_table *t = tab_create (nc, nr, 0);
+ struct tab_table *t = tab_create (nc, nr);
tab_title (t, _("Descriptive Statistics"));
- tab_dim (t, tab_natural_dimensions, NULL);
tab_headers (t, heading_columns, 0, heading_rows, 0);
gsl_eigen_symmv_sort (idata->eval, idata->evec, GSL_EIGEN_SORT_ABS_DESC);
#endif
+ idata->n_extractions = n_extracted_factors (factor, idata);
+
+ if (idata->n_extractions == 0)
+ {
+ msg (MW, _("The FACTOR criteria result in zero factors extracted. Therefore no analysis will be performed."));
+ goto finish;
+ }
+
+ if (idata->n_extractions > factor->n_vars)
+ {
+ msg (MW, _("The FACTOR criteria result in more factors than variables, which is not meaningful. No analysis will be performed."));
+ goto finish;
+ }
+
{
const gsl_vector *extracted_eigenvalues = NULL;
gsl_vector *initial_communalities = gsl_vector_alloc (factor->n_vars);
gsl_vector *extracted_communalities = gsl_vector_alloc (factor->n_vars);
size_t i;
- struct factor_matrix_workspace *fmw = factor_matrix_workspace_alloc (idata->msr->size, n_extracted_factors (factor, idata));
+ struct factor_matrix_workspace *fmw = factor_matrix_workspace_alloc (idata->msr->size, idata->n_extractions);
gsl_matrix *factor_matrix = gsl_matrix_calloc (factor->n_vars, fmw->n_factors);
if ( factor->extraction == EXTRACTION_PAF)
}
else if (factor->extraction == EXTRACTION_PC)
{
- for (i = 0 ; i < factor->n_vars; ++i)
- {
- gsl_vector_set (initial_communalities, i, communality (idata, i, factor->n_vars));
- }
+ for (i = 0; i < factor->n_vars; ++i)
+ gsl_vector_set (initial_communalities, i, communality (idata, i, factor->n_vars));
+
gsl_vector_memcpy (extracted_communalities, initial_communalities);
iterate_factor_matrix (analysis_matrix, extracted_communalities, factor_matrix, fmw);
factor_matrix_workspace_free (fmw);
+ show_scree (factor, idata);
+
show_factor_matrix (factor, idata, factor_matrix);
gsl_vector_free (initial_communalities);
gsl_vector_free (extracted_communalities);
}
+ finish:
+
idata_free (idata);
casereader_destroy (r);
#include <ctype.h>
#include <sys/types.h>
#include <regex.h>
+#include <libpspp/cast.h>
#include <libpspp/message.h>
#include <gtk/gtk.h>
buttonbox = get_widget_assert (fd.xml, "find-buttonbox");
- gtk_box_pack_start_defaults (GTK_BOX (buttonbox), find_button);
+ psppire_box_pack_start_defaults (GTK_BOX (buttonbox), find_button);
gtk_box_reorder_child (GTK_BOX (buttonbox), find_button, 0);
dialog = get_widget_assert (fd.xml, "find-dialog");
static void
regexp_destroy (struct comparator *cmptr)
{
- struct regexp_comparator *rec = (struct regexp_comparator *) cmptr;
+ struct regexp_comparator *rec
+ = UP_CAST (cmptr, struct regexp_comparator, parent);
regfree (&rec->re);
}
static void
cmptr_value_destroy (struct comparator *cmptr)
{
- struct value_comparator *vc = (struct value_comparator *) cmptr;
+ struct value_comparator *vc
+ = UP_CAST (cmptr, struct value_comparator, parent);
value_destroy (&vc->pattern, var_get_width (cmptr->var));
}
value_comparator_create (const struct variable *var, const PsppireDict *dict, const char *target)
{
struct value_comparator *vc = xzalloc (sizeof (*vc));
- struct comparator *cmptr = (struct comparator *) vc;
+ struct comparator *cmptr = &vc->parent;
cmptr->flags = 0;
cmptr->var = var;
enum string_cmp_flags flags)
{
struct string_comparator *ssc = xzalloc (sizeof (*ssc));
- struct comparator *cmptr = (struct comparator *) ssc;
+ struct comparator *cmptr = &ssc->parent;
cmptr->flags = flags;
cmptr->var = var;
{
int code;
struct regexp_comparator *rec = xzalloc (sizeof (*rec));
- struct comparator *cmptr = (struct comparator *) rec;
+ struct comparator *cmptr = &rec->parent;
cmptr->flags = flags;
cmptr->var = var;