From: John Darrington Date: Mon, 16 Sep 2013 06:49:43 +0000 (+0200) Subject: FACTOR: Fix bug interpreting the /CRITERIA=ITERATE subcommand X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3eb4b3858bc911dd79e3da5fdcb96151eeaecd4d;p=pspp FACTOR: Fix bug interpreting the /CRITERIA=ITERATE subcommand --- diff --git a/doc/statistics.texi b/doc/statistics.texi index 0f1c886f1b..03e4a44e4c 100644 --- a/doc/statistics.texi +++ b/doc/statistics.texi @@ -705,13 +705,23 @@ performed, and all coefficients will be printed. The @subcmd{/CRITERIA} subcommand is used to specify how the number of extracted factors (components) are chosen. If @subcmd{FACTORS(@var{n})} is specified, where @var{n} is an integer, then @var{n} factors will be extracted. Otherwise, the @subcmd{MINEIGEN} setting will -be used. @subcmd{MINEIGEN(@var{l})} requests that all factors whose eigenvalues are greater than or equal to @var{l} are extracted. -The default value of @var{l} is 1. The @subcmd{ECONVERGE} and @subcmd{ITERATE} settings have effect only when iterative algorithms for factor -extraction (such as Principal Axis Factoring) are used. @subcmd{ECONVERGE(@var{delta})} specifies that +be used. +@subcmd{MINEIGEN(@var{l})} requests that all factors whose eigenvalues are greater than or equal to @var{l} are extracted. +The default value of @var{l} is 1. +The @subcmd{ECONVERGE} setting has effect only when iterative algorithms for factor +extraction (such as Principal Axis Factoring) are used. +@subcmd{ECONVERGE(@var{delta})} specifies that iteration should cease when the maximum absolute value of the communality estimate between one iteration and the previous is less than @var{delta}. The default value of @var{delta} is 0.001. -The @subcmd{ITERATE(@var{m})} setting sets the maximum number of iterations to @var{m}. The default value of @var{m} is 25. +The @subcmd{ITERATE(@var{m})} may appear any number of times and is used for two different purposes. +It is used to set the maximum number of iterations (@var{m}) for convergence and also to set the maximum number of iterations +for rotation. +Whether it affects convergence or rotation depends upon which subcommand follows the @subcmd{ITERATE} subcommand. +If @subcmd{EXTRACTION} follows, it affects convergence. +If @subcmd{ROTATION} follows, it affects rotation. +If neither @subcmd{ROTATION} nor @subcmd{EXTRACTION} follow a @subcmd{ITERATE} subcommand it will be ignored. +The default value of @var{m} is 25. The @cmd{MISSING} subcommand determines the handling of missing variables. If @subcmd{INCLUDE} is set, then user-missing values are included in the diff --git a/src/language/stats/factor.c b/src/language/stats/factor.c index f393326843..fa9987332f 100644 --- a/src/language/stats/factor.c +++ b/src/language/stats/factor.c @@ -152,12 +152,13 @@ struct cmd_factor enum extraction_method extraction; enum plot_opts plot; enum rotation_type rotation; + int rotation_iterations; /* Extraction Criteria */ int n_factors; double min_eigen; double econverge; - int iterations; + int extraction_iterations; double rconverge; @@ -658,7 +659,7 @@ rotate (const struct cmd_factor *cf, const gsl_matrix *unrot, /* Now perform the rotation iterations */ prev_sv = initial_sv (normalised); - for (i = 0 ; i < cf->iterations ; ++i) + for (i = 0 ; i < cf->rotation_iterations ; ++i) { double sv = 0.0; for (j = 0 ; j < normalised->size2; ++j) @@ -814,7 +815,7 @@ int cmd_factor (struct lexer *lexer, struct dataset *ds) { const struct dictionary *dict = dataset_dict (ds); - + int n_iterations = 25; struct cmd_factor factor; factor.n_vars = 0; factor.vars = NULL; @@ -825,7 +826,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) factor.extraction = EXTRACTION_PC; factor.n_factors = 0; factor.min_eigen = SYSMIS; - factor.iterations = 25; + factor.extraction_iterations = 25; + factor.rotation_iterations = 25; factor.econverge = 0.001; factor.blank = 0; @@ -926,6 +928,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) goto error; } } + factor.rotation_iterations = n_iterations; } else if (lex_match_id (lexer, "CRITERIA")) { @@ -977,7 +980,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) if ( lex_force_match (lexer, T_LPAREN)) { lex_force_int (lexer); - factor.iterations = lex_integer (lexer); + n_iterations = lex_integer (lexer); lex_get (lexer); lex_force_match (lexer, T_RPAREN); } @@ -986,7 +989,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) { factor.n_factors = 0; factor.min_eigen = 1; - factor.iterations = 25; + n_iterations = 25; } else { @@ -1022,6 +1025,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds) goto error; } } + factor.extraction_iterations = n_iterations; } else if (lex_match_id (lexer, "FORMAT")) { @@ -1955,7 +1959,7 @@ do_factor (const struct cmd_factor *factor, struct casereader *r) gsl_vector_memcpy (initial_communalities, idata->msr); - for (i = 0; i < factor->iterations; ++i) + for (i = 0; i < factor->extraction_iterations; ++i) { double min, max; gsl_vector_memcpy (diff, idata->msr); diff --git a/tests/language/stats/factor.at b/tests/language/stats/factor.at index b26af0a7c9..d40cd28e92 100644 --- a/tests/language/stats/factor.at +++ b/tests/language/stats/factor.at @@ -1868,3 +1868,56 @@ TRAIT4,.97,.21,-.04,.00 TRAIT5,.70,-.67,-.23,.00 ]) AT_CLEANUP + + + +dnl Fixes a bug in the way that the /CRITERIA = ITERATE option was interpreted. +dnl http://lists.gnu.org/archive/html/bug-gnu-pspp/2013-09/msg00036.html +AT_SETUP([FACTOR /CRITERIA=ITERATE]) +AT_DATA([factor-iterate.sps], [dnl +set format = F20.3. +data list notable list /x y z *. +begin data. +1.00 5.00 3.00 +2.00 2.00 2.00 +3.00 1.00 1.00 +4.00 4.00 5.00 +5.00 3.00 9.00 +6.00 6.00 4.00 +7.00 7.00 6.00 +8.00 8.00 8.00 +9.00 9.00 7.00 +end data. + +FACTOR + /VARIABLES= x y z + /CRITERIA = MINEIGEN (1) ITERATE (25) + /EXTRACTION =PAF + /METHOD = CORRELATION + /PRINT = INITIAL EXTRACTION + /CRITERIA = ITERATE (0) + /ROTATION = NOROTATE. +]) + +AT_CHECK([pspp -O format=csv factor-iterate.sps], [0], [dnl +Table: Communalities +,Initial,Extraction +x,.735,.979 +y,.640,.653 +z,.514,.523 + +Table: Total Variance Explained +,Initial Eigenvalues,,,Extraction Sums of Squared Loadings,, +Factor,Total,% of Variance,Cumulative %,Total,% of Variance,Cumulative % +1,2.404,80.124,80.124,2.155,71.847,71.847 +2,.425,14.166,94.290,,, +3,.171,5.710,100.000,,, + +Table: Factor Matrix +,Factor +,1 +x,.990 +y,.808 +z,.723 +]) +AT_CLEANUP \ No newline at end of file