Merge "output" into "master"
authorBen Pfaff <blp@gnu.org>
Mon, 8 Feb 2010 04:22:31 +0000 (20:22 -0800)
committerBen Pfaff <blp@gnu.org>
Mon, 8 Feb 2010 04:37:35 +0000 (20:37 -0800)
1  2 
.gitignore
doc/automake.mk
src/language/stats/aggregate.c
src/language/stats/factor.c
src/ui/gui/automake.mk
src/ui/gui/find-dialog.c
src/ui/gui/helper.c

diff --combined .gitignore
index 56d869b2b4951552e97c3d0a5afdf2794216bce1,f8c59fe0c75a72c414585427f21303daca8261b7..c24b805ae8a18a367325e18fd5268672480a848c
@@@ -39,4 -39,5 +39,6 @@@ gitlog-to-changelo
  *.deps
  *.la
  *.libs
+ /arg-nonnull.h
 +/package.m4
+ /unused-parameter.h
diff --combined doc/automake.mk
index b1065a8d259c2982e4e6677a69b59022bf909cbd,504fb8a7bd7522ef1a74335d5392f60087f5c387..7645925bddf83cb65de71550ea5ff1fcd3d540d5
@@@ -6,6 -6,7 +6,6 @@@ doc_pspp_TEXINFOS = doc/version.texi 
        doc/bugs.texi \
        doc/command-index.texi \
        doc/concept-index.texi \
 -      doc/configuring.texi \
        doc/data-io.texi \
        doc/data-selection.texi \
        doc/expressions.texi \
@@@ -61,7 -62,7 +61,7 @@@ doc/pspp.xml: doc/pspp.texinfo $(doc_ps
  
  docbookdir = $(docdir)
  docbook_DATA = doc/pspp.xml
+ EXTRA_DIST += doc/pspp.xml
  
  EXTRA_DIST += doc/OChangeLog
  CLEANFILES += pspp-dev.dvi $(docbook_DATA)
index 891e0ccaa3cb8f7c4bb4ba0da73feb1d456a1843,ac7a2080bf02cc373e2f3ba53a0c9b444f2d9ffa..b3d02e141346ba2bb2bf8eccd60fa1665c3015cf
@@@ -196,6 -196,7 +196,7 @@@ cmd_aggregate (struct lexer *lexer, str
    dict_set_documents (agr.dict, dict_get_documents (dict));
  
    /* OUTFILE subcommand must be first. */
+   lex_match (lexer, '/');
    if (!lex_force_match_id (lexer, "OUTFILE"))
      goto error;
    lex_match (lexer, '=');
@@@ -965,20 -966,20 +966,20 @@@ dump_aggregate_info (struct agr_proc *a
          case MEDIAN:
            {
              struct casereader *sorted_reader;
 -            struct order_stats *median = percentile_create (0.5, i->cc);
 +            struct percentile *median = percentile_create (0.5, i->cc);
 +              struct order_stats *os = &median->parent;
  
              sorted_reader = casewriter_make_reader (i->writer);
  
 -            order_stats_accumulate (&median, 1,
 +            order_stats_accumulate (&os, 1,
                                      sorted_reader,
                                      i->weight,
                                      i->subject,
                                      i->exclude);
  
 -            v->f = percentile_calculate ((struct percentile *) median,
 -                                         PC_HAVERAGE);
 +            v->f = percentile_calculate (median, PC_HAVERAGE);
  
 -            statistic_destroy ((struct statistic *) median);
 +            statistic_destroy (&median->parent.parent);
            }
            break;
          case SD:
index 29e30c16b4b022b3eb26858507562dedc90f6d0e,cfec4a9a40890d7eb09a4c6bbdcc05c98d810bcd..58d5b868eb5be5d5d2fc685ed1466b4ae40dd52e
@@@ -1,5 -1,5 +1,5 @@@
  /* 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)
@@@ -72,12 -70,6 +72,12 @@@ enum extraction_metho
      EXTRACTION_PAF,
    };
  
 +enum plot_opts
 +  {
 +    PLOT_SCREE = 0x0001,
 +    PLOT_ROTATION = 0x0002
 +  };
 +
  enum print_opts
    {
      PRINT_UNIVARIATE  = 0x0001,
@@@ -108,7 -100,6 +108,7 @@@ struct cmd_facto
    enum mv_class exclude;
    enum print_opts print;
    enum extraction_method extraction;
 +  enum plot_opts plot;
  
    /* Extraction Criteria */
    int n_factors;
@@@ -535,7 -526,6 +535,7 @@@ cmd_factor (struct lexer *lexer, struc
    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"))
@@@ -921,22 -914,6 +924,22 @@@ communality (struct idata *idata, int n
  }
  
  
 +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;
@@@ -1010,7 -989,7 +1013,7 @@@ static voi
  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 )
@@@ -1128,10 -1109,12 +1131,10 @@@ show_explained_variance (const struct c
    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);
@@@ -1278,10 -1261,12 +1281,10 @@@ show_correlation_matrix (const struct c
    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)
@@@ -1421,8 -1406,9 +1424,8 @@@ do_factor (const struct cmd_factor *fac
  
        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);
diff --combined src/ui/gui/automake.mk
index cb730ec2def0bee1c0cde000f67294a4db7df2e4,0a827a3a489876cba70598abcf2ee7fbc946a576..a9b6f2123caa9573c35824858ddef552ed3bbb89
@@@ -26,7 -26,6 +26,7 @@@ src_ui_gui_psppire_LDADD = 
        src/libpspp.la \
        src/libpspp-core.la \
        $(GTK_LIBS) \
 +      $(CAIRO_LIBS) \
        $(LIBINTL)
  
  src_ui_gui_psppiredir = $(pkgdatadir)
@@@ -59,8 -58,10 +59,9 @@@ UI_FILES = 
        src/ui/gui/crosstabs.ui \
        src/ui/gui/descriptives.ui \
        src/ui/gui/examine.ui \
+       src/ui/gui/factor.ui \
        src/ui/gui/find.ui \
        src/ui/gui/frequencies.ui \
 -      src/ui/gui/message-dialog.ui \
        src/ui/gui/oneway.ui \
        src/ui/gui/psppire.ui \
        src/ui/gui/rank.ui \
@@@ -133,6 -134,8 +134,8 @@@ src_ui_gui_psppire_SOURCES = 
        src/ui/gui/executor.h \
        src/ui/gui/find-dialog.c \
        src/ui/gui/find-dialog.h \
+       src/ui/gui/factor-dialog.c \
+       src/ui/gui/factor-dialog.h \
        src/ui/gui/frequencies-dialog.c \
        src/ui/gui/frequencies-dialog.h \
        src/ui/gui/goto-case-dialog.c \
        src/ui/gui/helper.c \
        src/ui/gui/helper.h \
        src/ui/gui/main.c \
 -      src/ui/gui/message-dialog.c \
 -      src/ui/gui/message-dialog.h \
        src/ui/gui/missing-val-dialog.c \
        src/ui/gui/missing-val-dialog.h \
          src/ui/gui/oneway-anova-dialog.c \
diff --combined src/ui/gui/find-dialog.c
index 2319fb9f50fac2231169692fe837e395186af8a7,d72116069884cf3a21a199a7615b8e400a8657b5..ca0c3b5f4a9bb20b378792db2c7f1664a5d44b46
@@@ -34,7 -34,6 +34,7 @@@ which match particular strings *
  #include <ctype.h>
  #include <sys/types.h>
  #include <regex.h>
 +#include <libpspp/cast.h>
  #include <libpspp/message.h>
  
  #include <gtk/gtk.h>
@@@ -208,7 -207,7 +208,7 @@@ find_dialog (GObject *o, gpointer data
  
    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");
@@@ -567,8 -566,7 +567,8 @@@ regexp_label_compare (const struct comp
  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));
  }
  
@@@ -586,7 -583,7 +586,7 @@@ static struct comparator 
  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;
@@@ -605,7 -602,7 +605,7 @@@ string_comparator_create (const struct 
                          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;
@@@ -628,7 -625,7 +628,7 @@@ regexp_comparator_create (const struct 
  {
    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;
diff --combined src/ui/gui/helper.c
index 38110f5c1d7d18043b9b003856ce8dc5efbd4054,3e53f1ecb2e2ece73aa5d3a60d4d4fc8a0a4e206..377f17a7f6f77dae93e73a59e02fd31a95f5ae15
@@@ -24,6 -24,7 +24,6 @@@
  
  #include <glib.h>
  #include "helper.h"
 -#include "message-dialog.h"
  #include <data/format.h>
  #include <data/data-in.h>
  #include <data/data-out.h>
@@@ -299,3 -300,12 +299,12 @@@ paste_syntax_in_new_window (const gcha
  
    gtk_widget_show (se);
  }
+ /* gtk_box_pack_start_defaults is deprecated.
+    Therefore we roll our own until a better solution is found */
+ void
+ psppire_box_pack_start_defaults (GtkBox *box, GtkWidget *widget)
+ {
+   gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
+ }