+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)
+{
+ struct covariance_accumulator *ca;
+ struct covariance_accumulator *new_entry;
+
+ 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, 1.0);
+ ca->sum2 = update_sum (ca->v2, ca->val2, 1.0);
+ ca->ssize = 1.0;
+ new_entry = hsh_insert (c, ca);
+
+ if (new_entry != NULL)
+ {
+ new_entry->dot_product += ca->dot_product;
+ new_entry->ssize += 1.0;
+ new_entry->sum1 += ca->sum1;
+ new_entry->sum2 += ca->sum2;
+ /*
+ If DOT_PRODUCT is null, CA was not already in the hash
+ hable, so we don't free it because it was just inserted.
+ If DOT_PRODUCT was not null, CA is already in the hash table.
+ Unnecessary now, it must be freed here.
+ */
+ free (ca);
+ }
+}
+
+static void
+inner_intr_loop (struct covariance_matrix *cov, const struct ccase *ccase, const struct variable *var1,
+ const union value *val1, const struct interaction_variable **i_var,
+ const struct interaction_value *i_val1, size_t j)
+{
+ struct variable *var2;
+ union value *val2;
+ struct interaction_value *i_val2;
+
+ var2 = interaction_get_variable (i_var[j]);
+ i_val2 = interaction_case_data (ccase, i_var[j]);
+ val2 = interaction_value_get (i_val2);
+
+ if (!var_is_value_missing (var2, val2, cov->missing_value))
+ {
+ update_hash_entry_intr (cov->ca, var1, var2, val1, val2, i_val1, i_val2);
+ }
+}