byteswap \
c-ctype \
c-strtod \
+ close \
crypto/md4 \
dirname \
environ \
AM_CONDITIONAL(WITHCHARTS, test x"$with_libplot" != x"no")
+AC_ARG_VAR([PSPP_LDFLAGS], [linker flags to be used for linking the pspp binary only])
+AC_ARG_VAR([PSPPIRE_LDFLAGS], [linker flags to be used for linking the psppire binary only])
+
+
AC_ARG_WITH(
gui,
[AS_HELP_STRING([--without-gui], [don't build the PSPPIRE gui])])
msgid "An I/O error occurred writing system file \"%s\"."
msgstr ""
-#: src/data/variable.c:236
+#: src/data/variable.c:240
#, c-format
msgid ""
"Character `%c' (in %s) may not appear as the first character in a variable "
"name."
msgstr ""
-#: src/data/variable.c:248
+#: src/data/variable.c:252
#, c-format
msgid "Character `%c' (in %s) may not appear in a variable name."
msgstr ""
-#: src/data/variable.c:276
+#: src/data/variable.c:280
msgid "Variable name cannot be empty string."
msgstr ""
-#: src/data/variable.c:282
+#: src/data/variable.c:286
#, c-format
msgid "Variable name %s exceeds %d-character limit."
msgstr ""
-#: src/data/variable.c:290
+#: src/data/variable.c:294
#, c-format
msgid "`%s' may not be used as a variable name because it is a reserved word."
msgstr ""
msgid "Only USE ALL is currently implemented."
msgstr ""
-#: src/language/utilities/include.c:90
+#: src/language/utilities/include.c:92
msgid "Expecting BATCH or INTERACTIVE after SYNTAX."
msgstr ""
-#: src/language/utilities/include.c:107
+#: src/language/utilities/include.c:109
msgid "Expecting YES or NO after CD."
msgstr ""
-#: src/language/utilities/include.c:124
+#: src/language/utilities/include.c:126
msgid "Expecting CONTINUE or STOP after ERROR."
msgstr ""
-#: src/language/utilities/include.c:131
+#: src/language/utilities/include.c:133
#, c-format
msgid "Unexpected token: `%s'."
msgstr ""
-#: src/language/utilities/include.c:176
+#: src/language/utilities/include.c:178
msgid "expecting file name"
msgstr ""
-#: src/language/utilities/include.c:188
+#: src/language/utilities/include.c:190
#, c-format
msgid "Can't find `%s' in include file search path."
msgstr ""
+#: src/language/utilities/include.c:198
+#, c-format
+msgid "Unable to open `%s': %s."
+msgstr ""
+
#: src/language/utilities/permissions.c:73
#, c-format
msgid "Expecting %s or %s."
msgid "unknown configuration parameter `%s' for HTML device driver"
msgstr ""
-#: src/output/journal.c:68
+#: src/output/journal.c:69
#, c-format
msgid "error writing \"%s\""
msgstr ""
-#: src/output/journal.c:90
+#: src/output/journal.c:94
#, c-format
msgid "error creating \"%s\""
msgstr ""
msgid "Paste"
msgstr ""
-#: src/ui/gui/psppire.c:214
+#: src/ui/gui/psppire.c:226
msgid "_Reset"
msgstr ""
-#: src/ui/gui/psppire.c:215
+#: src/ui/gui/psppire.c:227
msgid "_Select"
msgstr ""
-#: src/ui/gui/psppire.c:251
+#: src/ui/gui/psppire.c:263
#, c-format
msgid "Cannot open %s: %s.\n"
msgstr ""
-#: src/ui/gui/psppire.c:268
+#: src/ui/gui/psppire.c:280
#, c-format
msgid "%s is neither a system nor portable file"
msgstr ""
hash ^= hsh_hash_string (identity->name);
return hash;
}
+
+
+
+#ifdef WINDOWS32
+
+/* Apparently windoze users like to see output dumped into their home directory,
+ not the current directory (!) */
+const char *
+default_output_path (void)
+{
+ static const char *home_dir = NULL;
+
+ /* Windows NT defines HOMEDRIVE and HOMEPATH. But give preference
+ to HOME, because the user can change HOME. */
+ if (home_dir == NULL)
+ {
+ const char *home_drive = getenv ("HOMEDRIVE");
+ const char *home_path = getenv ("HOMEPATH");
+
+ if (home_drive != NULL && home_path != NULL)
+ home_dir = xasprintf ("%s%s%c",
+ home_drive, home_path, DIRECTORY_SEPARATOR);
+ else
+ home_dir = "c:/users/default/"; /* poor default */
+ }
+ return home_dir;
+}
+
+#else
+
+/* ... whereas the rest of the world just likes it to be
+ put "here" for easy access. */
+const char *
+default_output_path (void)
+{
+ static char current_dir[] = "";
+
+ return current_dir;
+}
+
+#endif
+
const struct file_identity *);
unsigned int fn_hash_identity (const struct file_identity *);
+const char * default_output_path (void);
+
#endif /* file-name.h */
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2009 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
return new_var;
}
-/* Create a variable to be used for internal calculations only */
+/* Create a variable to be used for internal calculations only.
+ The variable is assigned a unique dictionary index and a case
+ index of CASE_IDX. */
struct variable *
var_create_internal (int case_idx)
{
struct variable *v = var_create ("$internal", 0);
-
struct vardict_info vdi;
+ static int counter = INT_MAX / 2;
vdi.dict = NULL;
- vdi.dict_index = 0;
vdi.case_index = case_idx;
+ vdi.dict_index = counter++;
+ if (counter == INT_MAX)
+ counter = INT_MAX / 2;
var_set_vardict (v, &vdi);
DEF_CMD (S_DATA, 0, "AGGREGATE", cmd_aggregate)
DEF_CMD (S_DATA, 0, "AUTORECODE", cmd_autorecode)
DEF_CMD (S_DATA, F_KEEP_FINAL_TOKEN, "BEGIN DATA", cmd_begin_data)
-DEF_CMD (S_DATA, 0, "CORRELATIONS", cmd_correlations)
DEF_CMD (S_DATA, 0, "COUNT", cmd_count)
DEF_CMD (S_DATA, 0, "CROSSTABS", cmd_crosstabs)
DEF_CMD (S_DATA, 0, "DELETE VARIABLES", cmd_delete_variables)
DEF_CMD (S_DATA, 0, "MODIFY VARS", cmd_modify_vars)
DEF_CMD (S_DATA, 0, "NPAR TESTS", cmd_npar_tests)
DEF_CMD (S_DATA, 0, "ONEWAY", cmd_oneway)
-DEF_CMD (S_DATA, 0, "PEARSON CORRELATIONS", cmd_correlations)
DEF_CMD (S_DATA, 0, "RANK", cmd_rank)
DEF_CMD (S_DATA, 0, "REGRESSION", cmd_regression)
DEF_CMD (S_DATA, 0, "RELIABILITY", cmd_reliability)
UNIMPL_CMD ("CLEAR TRANSFORMATIONS", "Clears transformations from active file")
UNIMPL_CMD ("CLUSTER", "Hierachial clustering")
UNIMPL_CMD ("CONJOINT", "Analyse full concept data")
+UNIMPL_CMD ("CORRELATIONS", "Correlation coefficients")
UNIMPL_CMD ("CORRESPONDENCE", "Show correspondence")
UNIMPL_CMD ("COXREG", "Cox proportional hazards regression")
UNIMPL_CMD ("CREATE", "Create time series data")
UNIMPL_CMD ("OVERALS", "Nonlinear canonical correlation")
UNIMPL_CMD ("PACF", "Partial autocorrelation")
UNIMPL_CMD ("PARTIAL CORR", "Partial correlation")
+UNIMPL_CMD ("PEARSON CORRELATIONS", "Correlation coefficients")
UNIMPL_CMD ("PLANCARDS", "Conjoint analysis planning")
UNIMPL_CMD ("PLUM", "Estimate ordinal regression models")
UNIMPL_CMD ("POINT", "Marker in keyed file")
int width = var_get_width (var);
if (var_is_value_missing (var, value, exclude))
- break;
+ continue;
if ( NULL == cat1[v].value )
{
if ( bst->category1 != SYSMIS )
{
+ int i;
union value v;
v.f = bst->category1;
- cat1->value = value_dup (&v, 0);
+ for (i = 0; i < ost->n_vars; i++)
+ cat1[i].value = value_dup (&v, 0);
}
if ( bst->category2 != SYSMIS )
{
+ int i;
union value v;
v.f = bst->category2;
- cat2->value = value_dup (&v, 0);
+ for (i = 0; i < ost->n_vars; i++)
+ cat2[i].value = value_dup (&v, 0);
}
if (do_binomial (dataset_dict(ds), input, bst, cat1, cat2, exclude))
if (mode == GENERAL)
{
- int width = var_get_width (v);
+ int width = MIN (var_get_width (v), MAX_SHORT_STRING);
int i;
*values = xnmalloc (entry_cnt, sizeof **values);
/*
Accumulate the covariance matrix.
*/
- covariance_matrix_accumulate (cov, c);
+ covariance_matrix_accumulate (cov, c, NULL, 0);
n_data++;
}
covariance_matrix_compute (cov);
#include <config.h>
#include <ctype.h>
+#include <errno.h>
#include <stdlib.h>
+#include <string.h>
#include <language/command.h>
#include <libpspp/message.h>
#include <libpspp/getl.h>
}
*filename = relative_filename;
+ if (*filename == NULL)
+ {
+ msg (SE, _("Unable to open `%s': %s."),
+ relative_filename, strerror (errno));
+ free (relative_filename);
+ return CMD_FAILURE;
+ }
return CMD_SUCCESS;
}
nodist_src_libpspp_libpspp_la_SOURCES = src/libpspp/version.c
-src/libpspp/version.c: $(top_srcdir)/AUTHORS $(top_builddir)/Makefile
+src/libpspp/version.c: $(top_srcdir)/AUTHORS Makefile
@$(MKDIR_P) src/libpspp
echo "/* -*- mode: c; buffer-read-only: t -*-" > $@
echo " Generated by src/libpspp/automake.mk --- Do not edit.">> $@
int n_pass;
int missing_handling;
enum mv_class missing_value;
- void (*accumulate) (struct covariance_matrix *, const struct ccase *);
+ void (*accumulate) (struct covariance_matrix *, const struct ccase *,
+ const struct interaction_variable **, size_t);
void (*update_moments) (struct covariance_matrix *, size_t, double);
};
+
+
static struct hsh_table *covariance_hsh_create (size_t);
static hsh_hash_func covariance_accumulator_hash;
static unsigned int hash_numeric_alpha (const struct variable *,
value
*);
static void covariance_accumulate_listwise (struct covariance_matrix *,
- const struct ccase *);
+ const struct ccase *,
+ const struct interaction_variable **,
+ size_t);
static void covariance_accumulate_pairwise (struct covariance_matrix *,
- const struct ccase *);
+ const struct ccase *,
+ const struct interaction_variable **,
+ size_t);
struct covariance_matrix *
covariance_matrix_init (size_t n_variables,
col += i;
y = -1.0 * cat_get_category_count (i, v) / ssize;
tmp_val = cat_subscript_to_value (i, v);
- if (compare_values_short (tmp_val, val1, v))
+ if (!compare_values_short (tmp_val, val1, v))
{
y += -1.0;
}
row += i;
x = -1.0 * cat_get_category_count (i, v1) / ssize;
tmp_val = cat_subscript_to_value (i, v1);
- if (compare_values_short (tmp_val, val1, v1))
+ if (!compare_values_short (tmp_val, val1, v1))
{
x += 1.0;
}
}
if (var_is_numeric (v1) && var_is_alpha (v2))
{
- if (compare_values_short (val2, c->val2, v2))
+ if (!compare_values_short (val2, c->val2, v2))
{
return 0;
}
}
if (var_is_alpha (v1) && var_is_numeric (v2))
{
- if (compare_values_short (val1, c->val1, v1))
+ if (!compare_values_short (val1, c->val1, v1))
{
return 0;
}
}
if (var_is_alpha (v1) && var_is_alpha (v2))
{
- if (compare_values_short (val1, c->val1, v1))
+ if (!compare_values_short (val1, c->val1, v1))
{
- if (compare_values_short (val2, c->val2, v2))
+ if (!compare_values_short (val2, c->val2, v2))
{
return 0;
}
return 0.0;
}
static double
-update_sum (const struct variable *var, const union value *val)
+update_sum (const struct variable *var, const union value *val, double weight)
{
assert (var != NULL);
assert (val != NULL);
if (var_is_alpha (var))
{
- return 1.0;
+ return weight;
}
return val->f;
}
return cov->v_variables;
}
+
static void
update_hash_entry (struct hsh_table *c,
const struct variable *v1,
const struct variable *v2,
- const union value *val1, const union value *val2)
+ const union value *val1, const union value *val2,
+ const struct interaction_value *i_val1,
+ const struct interaction_value *i_val2)
{
struct covariance_accumulator *ca;
struct covariance_accumulator *new_entry;
+ double iv_f1;
+ double iv_f2;
-
+ iv_f1 = interaction_value_get_nonzero_entry (i_val1);
+ iv_f2 = interaction_value_get_nonzero_entry (i_val2);
ca = get_new_covariance_accumulator (v1, v2, val1, val2);
ca->dot_product = update_product (ca->v1, ca->v2, ca->val1, ca->val2);
- ca->sum1 = update_sum (ca->v1, ca->val1);
- ca->sum2 = update_sum (ca->v2, ca->val2);
+ ca->dot_product *= iv_f1 * iv_f2;
+ ca->sum1 = update_sum (ca->v1, ca->val1, iv_f1);
+ ca->sum2 = update_sum (ca->v2, ca->val2, iv_f2);
ca->ssize = 1.0;
new_entry = hsh_insert (c, ca);
if (new_entry != NULL)
*/
static void
covariance_accumulate_pairwise (struct covariance_matrix *cov,
- const struct ccase *ccase)
+ const struct ccase *ccase,
+ const struct interaction_variable **i_var,
+ size_t n_intr)
{
size_t i;
size_t j;
const union value *val1;
const union value *val2;
const struct variable **v_variables;
+ struct interaction_value *i_val1 = NULL;
+ struct interaction_value *i_val2 = NULL;
assert (cov != NULL);
assert (ccase != NULL);
for (i = 0; i < cov->n_variables; ++i)
{
- val1 = case_data (ccase, v_variables[i]);
+ if (is_interaction (v_variables[i], i_var, n_intr))
+ {
+ i_val1 = interaction_case_data (ccase, v_variables[i], i_var, n_intr);
+ val1 = interaction_value_get (i_val1);
+ }
+ else
+ {
+ val1 = case_data (ccase, v_variables[i]);
+ }
if (!var_is_value_missing (v_variables[i], val1, cov->missing_value))
{
cat_value_update (v_variables[i], val1);
- if (var_is_alpha (v_variables[i]))
+ if (var_is_numeric (v_variables[i]))
cov->update_moments (cov, i, val1->f);
for (j = i; j < cov->n_variables; j++)
{
- val2 = case_data (ccase, v_variables[j]);
+ if (is_interaction (v_variables[j], i_var, n_intr))
+ {
+ i_val2 = interaction_case_data (ccase, v_variables[j], i_var, n_intr);
+ val2 = interaction_value_get (i_val2);
+ }
+ else
+ {
+ val2 = case_data (ccase, v_variables[j]);
+ }
if (!var_is_value_missing
(v_variables[j], val2, cov->missing_value))
{
update_hash_entry (cov->ca, v_variables[i], v_variables[j],
- val1, val2);
+ val1, val2, i_val1, i_val2);
if (j != i)
update_hash_entry (cov->ca, v_variables[j],
- v_variables[i], val2, val1);
+ v_variables[i], val2, val1, i_val2, i_val1);
}
}
}
*/
static void
covariance_accumulate_listwise (struct covariance_matrix *cov,
- const struct ccase *ccase)
+ const struct ccase *ccase,
+ const struct interaction_variable **i_var,
+ size_t n_intr)
{
size_t i;
size_t j;
const union value *val1;
const union value *val2;
const struct variable **v_variables;
+ struct interaction_value *i_val1 = NULL;
+ struct interaction_value *i_val2 = NULL;
assert (cov != NULL);
assert (ccase != NULL);
for (i = 0; i < cov->n_variables; ++i)
{
- val1 = case_data (ccase, v_variables[i]);
+ if (is_interaction (v_variables[i], i_var, n_intr))
+ {
+ i_val1 = interaction_case_data (ccase, v_variables[i], i_var, n_intr);
+ val1 = interaction_value_get (i_val1);
+ }
+ else
+ {
+ val1 = case_data (ccase, v_variables[i]);
+ }
cat_value_update (v_variables[i], val1);
- if (var_is_alpha (v_variables[i]))
+ if (var_is_numeric (v_variables[i]))
cov->update_moments (cov, i, val1->f);
for (j = i; j < cov->n_variables; j++)
{
- val2 = case_data (ccase, v_variables[j]);
+ if (is_interaction (v_variables[j], i_var, n_intr))
+ {
+ i_val2 = interaction_case_data (ccase, v_variables[j], i_var, n_intr);
+ val2 = interaction_value_get (i_val2);
+ }
+ else
+ {
+ val2 = case_data (ccase, v_variables[j]);
+ }
update_hash_entry (cov->ca, v_variables[i], v_variables[j],
- val1, val2);
+ val1, val2, i_val1, i_val2);
if (j != i)
update_hash_entry (cov->ca, v_variables[j], v_variables[i],
- val2, val1);
+ val2, val1, i_val2, i_val1);
}
}
}
Call this function during the data pass. Each case will be added to
a hash containing all values of the covariance matrix. After the
data have been passed, call covariance_matrix_compute to put the
- values in the struct covariance_matrix.
+ values in the struct covariance_matrix.
*/
void
covariance_matrix_accumulate (struct covariance_matrix *cov,
- const struct ccase *ccase)
+ const struct ccase *ccase, void **aux, size_t n_intr)
{
- cov->accumulate (cov, ccase);
+ cov->accumulate (cov, ccase, (const struct interaction_variable **) aux, n_intr);
}
static void
{
i = 0;
tmp_val = cat_subscript_to_value (i, v1);
- while (!compare_values_short (tmp_val, val1, v1))
+ while (compare_values_short (tmp_val, val1, v1))
{
i++;
tmp_val = cat_subscript_to_value (i, v1);
col = design_matrix_var_to_column (cov, v2);
i = 0;
tmp_val = cat_subscript_to_value (i, v1);
- while (!compare_values_short (tmp_val, val1, v1))
+ while (compare_values_short (tmp_val, val1, v1))
{
i++;
tmp_val = cat_subscript_to_value (i, v1);
#define COVARIANCE_MATRIX_H
#include <math/design-matrix.h>
+#include <math/interaction.h>
struct moments1;
struct ccase;
int, int, enum mv_class);
void covariance_matrix_free (struct covariance_matrix *);
void covariance_matrix_accumulate (struct covariance_matrix *,
- const struct ccase *);
+ const struct ccase *, void **, size_t);
struct design_matrix *covariance_to_design (const struct covariance_matrix *);
#endif
/* PSPP - a program for statistical analysis.
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2009 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
OBS_VALS member. If there are K categorical variables, each with
N_1, N_2, ..., N_K categories, then the interaction will have
N_1 * N_2 * N_3 *...* N_K - 1 entries.
+
+ When using these functions, make sure the orders of variables and
+ values match when appropriate.
*/
#include <config.h>
#include <assert.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_vector.h>
-#include <data/category.h>
+#include <data/value.h>
#include <data/variable.h>
-#include "interaction.h"
+#include <math/interaction.h>
+#include <string.h>
+#include <xalloc.h>
-#include "xalloc.h"
+struct interaction_variable
+{
+ int n_vars;
+ const struct variable **members;
+ struct variable *intr;
+ size_t n_alpha;
+};
+
+struct interaction_value
+{
+ const struct interaction_variable *intr;
+ union value *val; /* Concatenation of the string values in this
+ interaction's value, or the product of a bunch
+ of numeric values for a purely numeric
+ interaction.
+ */
+ double f; /* Product of the numerical values in this interaction's value. */
+};
/*
- Convert a list of values to a binary vector. The order of VALS must
- correspond to the order of V.
+ An interaction_variable has type alpha if any of members have type
+ alpha. Otherwise, its type is numeric.
*/
-gsl_vector *
-get_interaction (union value **vals, const struct variable **v, size_t n_vars)
+struct interaction_variable *
+interaction_variable_create (const struct variable **vars, int n_vars)
{
- gsl_vector *result = NULL;
- size_t *subs = NULL;
- size_t length = 1;
+ struct interaction_variable *result = NULL;
size_t i;
- size_t j;
- double tmp = 1.0;
- assert (n_vars > 0);
- for (i = 0; i < n_vars; i++)
+ if (n_vars > 0)
{
- if (var_is_alpha (v[i]))
+ result = xmalloc (sizeof (*result));
+ result->n_alpha = 0;
+ result->members = xnmalloc (n_vars, sizeof (*result->members));
+ result->intr = var_create_internal (0);
+ result->n_vars = n_vars;
+ for (i = 0; i < n_vars; i++)
{
- length *= cat_get_n_categories (v[i]);
+ result->members[i] = vars[i];
+ if (var_is_alpha (vars[i]))
+ {
+ result->n_alpha++;
+ }
}
- else
+ }
+ /*
+ VAR_SET_WIDTH sets the type of the variable.
+ */
+ var_set_width (result->intr, MAX_SHORT_STRING * result->n_alpha + 1);
+
+ return result;
+}
+void interaction_variable_destroy (struct interaction_variable *iv)
+{
+ var_destroy (iv->intr);
+ free (iv->members);
+ free (iv);
+}
+
+/*
+ Get one of the member variables.
+ */
+const struct variable *
+interaction_variable_get_member (const struct interaction_variable *iv, size_t i)
+{
+ return iv->members[i];
+}
+
+size_t
+interaction_get_n_vars (const struct interaction_variable *iv)
+{
+ return (iv == NULL) ? 0 : iv->n_vars;
+}
+
+size_t
+interaction_get_n_alpha (const struct interaction_variable *iv)
+{
+ return iv->n_alpha;
+}
+
+size_t
+interaction_get_n_numeric (const struct interaction_variable *iv)
+{
+ return (interaction_get_n_vars (iv) - interaction_get_n_alpha (iv));
+}
+
+/*
+ Get the interaction varibale itself.
+ */
+const struct variable *
+interaction_variable_get_var (const struct interaction_variable *iv)
+{
+ return iv->intr;
+}
+/*
+ Given list of values, compute the value of the corresponding
+ interaction. This "value" is not stored as the typical vector of
+ 0's and one double, but rather the string values are concatenated to
+ make one big string value, and the numerical values are multiplied
+ together to give the non-zero entry of the corresponding vector.
+ */
+struct interaction_value *
+interaction_value_create (const struct interaction_variable *var, const union value **vals)
+{
+ struct interaction_value *result = NULL;
+ const struct variable *member;
+ size_t i;
+ size_t n_vars;
+
+ if (var != NULL)
+ {
+ result = xmalloc (sizeof (*result));
+ result->intr = var;
+ n_vars = interaction_get_n_vars (var);
+ result->val = value_create (n_vars * MAX_SHORT_STRING + 1);
+ result->f = 1.0;
+ for (i = 0; i < n_vars; i++)
+ {
+ member = interaction_variable_get_member (var, i);
+
+ if (var_is_value_missing (member, vals[i], MV_ANY))
+ {
+ value_set_missing (result->val, MAX_SHORT_STRING);
+ result->f = SYSMIS;
+ break;
+ }
+ else
+ {
+ if (var_is_alpha (var->members[i]))
+ {
+ strncat (result->val->s, vals[i]->s, MAX_SHORT_STRING);
+ }
+ else if (var_is_numeric (var->members[i]))
+ {
+ result->f *= vals[i]->f;
+ }
+ }
+ }
+ if (interaction_get_n_alpha (var) == 0)
{
- length = (length > 0) ? length : 1;
+ /*
+ If there are no categorical variables, then the
+ interaction consists of only numeric data. In this case,
+ code that uses this interaction_value will see the union
+ member as the numeric value. If we were to store that
+ numeric value in result->f as well, the calling code may
+ inadvertently square this value by multiplying by
+ result->val->f. Such multiplication would be correct for an
+ interaction consisting of both categorical and numeric
+ data, but a mistake for purely numerical interactions. To
+ avoid the error, we set result->f to 1.0 for numeric
+ interactions.
+ */
+ result->val->f = result->f;
+ result->f = 1.0;
}
}
- if (length > 0)
+ return result;
+}
+
+union value *
+interaction_value_get (const struct interaction_value *val)
+{
+ return val->val;
+}
+
+/*
+ Returns the numeric value of the non-zero entry for the vector
+ corresponding to this interaction. Do not use this function to get
+ the numeric value of a purley numeric interaction. Instead, use the
+ union value * returned by interaction_value_get.
+ */
+double
+interaction_value_get_nonzero_entry (const struct interaction_value *val)
+{
+ if (val != NULL)
+ return val->f;
+ return 1.0;
+}
+
+void
+interaction_value_destroy (struct interaction_value *val)
+{
+ if (val != NULL)
{
- length--;
+ free (val->val);
+ free (val);
}
+}
- result = gsl_vector_calloc (length);
- subs = xnmalloc (n_vars, sizeof (*subs));
- for (j = 0; j < n_vars; j++)
+/*
+ Return a value from a variable that is an interaction.
+ */
+struct interaction_value *
+interaction_case_data (const struct ccase *ccase, const struct variable *var,
+ const struct interaction_variable **intr_vars, size_t n_intr)
+{
+ size_t i;
+ size_t n_vars;
+ const struct interaction_variable *iv;
+ const struct variable *intr;
+ const struct variable *member;
+ const union value **vals = NULL;
+
+ for (i = 0; i < n_intr; i++)
{
- if (var_is_alpha (v[j]))
+ iv = intr_vars[i];
+ intr = interaction_variable_get_var (iv);
+ if (var_get_dict_index (intr) == var_get_dict_index (var))
{
- subs[j] = cat_value_find (v[j], vals[j]);
+ break;
}
}
- j = subs[0];
- for (i = 1; i < n_vars; i++)
+ n_vars = interaction_get_n_vars (iv);
+ vals = xnmalloc (n_vars, sizeof (*vals));
+ for (i = 0; i < n_vars; i++)
{
- j = j * cat_get_n_categories (v[i]) + subs[i];
+ member = interaction_variable_get_member (iv, i);
+ vals[i] = case_data (ccase, member);
}
- gsl_vector_set (result, j, 1.0);
- /*
- If any of the variables are numeric, the interaction of that
- variable with another is just a scalar product.
- */
- for (i = 1; i < n_vars; i++)
+ return interaction_value_create (iv, vals);
+}
+
+bool
+is_interaction (const struct variable *var, const struct interaction_variable **iv, size_t n_intr)
+{
+ size_t i;
+ const struct variable *intr;
+
+ for (i = 0; i < n_intr; i++)
{
- if (var_is_numeric (v[i]))
+ intr = interaction_variable_get_var (iv[i]);
+ if (var_get_dict_index (intr) == var_get_dict_index (var))
{
- tmp *= vals[i]->f;
+ return true;
}
}
- if (fabs (tmp - 1.0) > GSL_DBL_EPSILON)
- {
- gsl_vector_set (result, j, tmp);
- }
- free (subs);
-
- return result;
+ return false;
}
+
/* PSPP - a program for statistical analysis.
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2009 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
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-gsl_vector *
-get_interaction (union value **, const struct variable **, size_t);
+#ifndef INTERACTION_H
+#define INTERACTION_H
+#include <data/case.h>
+
+struct interaction_variable;
+struct interaction_value;
+
+struct interaction_variable * interaction_variable_create (const struct variable **, int);
+void interaction_variable_destroy (struct interaction_variable *);
+struct interaction_value * interaction_value_create (const struct interaction_variable *, const union value **);
+void interaction_value_destroy (struct interaction_value *);
+size_t interaction_variable_get_n_vars (const struct interaction_variable *);
+double interaction_value_get_nonzero_entry (const struct interaction_value *);
+union value * interaction_value_get (const struct interaction_value *);
+const struct variable * interaction_variable_get_var (const struct interaction_variable *);
+size_t interaction_get_n_numeric (const struct interaction_variable *);
+size_t interaction_get_n_alpha (const struct interaction_variable *);
+size_t interaction_get_n_vars (const struct interaction_variable *);
+const struct variable * interaction_variable_get_member (const struct interaction_variable *, size_t);
+bool is_interaction (const struct variable *, const struct interaction_variable **, size_t);
+struct interaction_value *
+interaction_case_data (const struct ccase *, const struct variable *,
+ const struct interaction_variable **, size_t);
+double interaction_value_get_nonzero_entry (const struct interaction_value *);
+#endif
#include <stdio.h>
#include <stdlib.h>
+#include <data/file-name.h>
#include <libpspp/str.h>
#include "fwriteerror.h"
if (journal_file == NULL)
{
if (journal_file_name == NULL)
- journal_file_name = xstrdup ("pspp.jnl");
+ {
+ const char *output_path = default_output_path ();
+ journal_file_name = xasprintf ("%s%s", output_path, "pspp.jnl");
+ }
journal_file = fopen (journal_file_name, "w");
if (journal_file == NULL)
{
src_ui_gui_psppire_LDFLAGS = \
+ $(PSPPIRE_LDFLAGS) \
$(PG_LDFLAGS)
#include <config.h>
#include <gtk/gtk.h>
+#include <data/file-name.h>
#include "window-manager.h"
#include "output-viewer.h"
#include "helper.h"
the_output_viewer = NULL;
- unlink (OUTPUT_FILE_NAME);
+ unlink (output_file_name ());
return FALSE;
}
struct stat buf;
/* If there is no output, then don't do anything */
- if (0 != stat (OUTPUT_FILE_NAME, &buf))
+ if (0 != stat (output_file_name (), &buf))
return ;
if ( NULL == the_output_viewer )
reload_viewer (the_output_viewer);
}
+#define OUTPUT_FILE_NAME "psppire.txt"
void
reload_viewer (struct output_viewer *ov)
{
if ( ov->fp == NULL)
{
- ov->fp = fopen (OUTPUT_FILE_NAME, "r");
+ ov->fp = fopen (output_file_name (), "r");
if ( ov->fp == NULL)
{
- g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
+ g_print ("Cannot open %s\n", output_file_name ());
return;
}
}
+
+const char *
+output_file_name (void)
+{
+ const char *dir = default_output_path ();
+ static char *filename = NULL;
+
+ if ( NULL == filename )
+ filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME);
+
+
+ return filename;
+}
void reload_the_viewer (void);
-#define OUTPUT_FILE_NAME "psppire.txt"
-
+const char * output_file_name (void);
#endif
create_icon_factory ();
- outp_configure_driver_line (
- ss_cstr ("gui:ascii:screen:squeeze=on headers=off top-margin=0 "
- "bottom-margin=0 paginate=off length=auto width=auto "
- "emphasis=none "
- "output-file=\"" OUTPUT_FILE_NAME "\" append=yes"));
+ {
+ const char *filename = output_file_name ();
+
+ struct string config_string;
+
+ ds_init_empty (&config_string);
+
+ ds_put_format (&config_string,
+ "gui:ascii:screen:squeeze=on headers=off top-margin=0 "
+ "bottom-margin=0 paginate=off length=auto width=auto "
+ "emphasis=none "
+ "output-file=\"%s\" append=yes", filename);
- unlink (OUTPUT_FILE_NAME);
+ outp_configure_driver_line (ds_ss (&config_string));
+
+ unlink (filename);
+
+ ds_destroy (&config_string);
+ }
journal_enable ();
textdomain (PACKAGE);
@LIBINTL@ @LIBREADLINE@
-src_ui_terminal_pspp_LDFLAGS = $(PG_LDFLAGS)
+src_ui_terminal_pspp_LDFLAGS = $(PSPP_LDFLAGS) $(PG_LDFLAGS)
if RELOCATABLE_VIA_LD
src_ui_terminal_pspp_LDFLAGS += `$(RELOCATABLE_LDFLAGS) $(bindir)`
EOF
if [ $? -ne 0 ] ; then fail ; fi
+# Test for regression against bug #24569 in which PSPP crashed
+# upon attempt to insert a nonexistent file.
+activity="create wrapper 9"
+cat <<EOF > $TESTFILE
+INSERT
+ FILE='$TEMPDIR/nonexistent'
+ ERROR=CONTINUE.
+ .
+
+LIST.
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+#This command should fail
+activity="run program 7"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE > /dev/null
+if [ $? -eq 0 ] ; then no_result ; fi
+
pass;