lexer: New function lex_ofs_representation().
[pspp] / src / language / stats / matrix.c
index 64d8dd92f83873465a0727415c1604c3843a452c..37b565e05eba85cce43d341ff2b315a9212ac319 100644 (file)
@@ -1851,21 +1851,24 @@ matrix_eval_IDENT (double s1, double s2)
   return m;
 }
 
+/* Inverts X, storing the inverse into INVERSE.  As a side effect, replaces X
+   by its LU decomposition. */
 static void
-invert_matrix (gsl_matrix *x)
+invert_matrix (gsl_matrix *x, gsl_matrix *inverse)
 {
   gsl_permutation *p = gsl_permutation_alloc (x->size1);
   int signum;
   gsl_linalg_LU_decomp (x, p, &signum);
-  gsl_linalg_LU_invx (x, p);
+  gsl_linalg_LU_invert (x, p, inverse);
   gsl_permutation_free (p);
 }
 
 static gsl_matrix *
-matrix_eval_INV (gsl_matrix *m)
+matrix_eval_INV (gsl_matrix *src)
 {
-  invert_matrix (m);
-  return m;
+  gsl_matrix *dst = gsl_matrix_alloc (src->size1, src->size2);
+  invert_matrix (src, dst);
+  return dst;
 }
 
 static gsl_matrix *
@@ -3380,7 +3383,7 @@ matrix_expr_evaluate_exp_mat (const struct matrix_expr *e,
   if (bf != floor (bf) || bf <= LONG_MIN || bf > LONG_MAX)
     {
       msg_at (SE, matrix_expr_location (e->subs[1]),
-              _("Exponent %.1f in matrix multiplication is non-integer "
+              _("Exponent %.1f in matrix exponentiation is non-integer "
                 "or outside the valid range."), bf);
       return NULL;
     }
@@ -3405,7 +3408,10 @@ matrix_expr_evaluate_exp_mat (const struct matrix_expr *e,
 
   mul_matrix (&y, x, y, &t);
   if (bf < 0)
-    invert_matrix (y);
+    {
+      invert_matrix (y, x);
+      swap_matrix (&x, &y);
+    }
 
   /* Garbage collection.
 
@@ -5361,25 +5367,12 @@ matrix_print_parse (struct matrix_state *s)
 
   if (lex_token (s->lexer) != T_SLASH && lex_token (s->lexer) != T_ENDCMD)
     {
-      size_t depth = 0;
-      for (size_t i = 0; ; i++)
-        {
-          enum token_type t = lex_next_token (s->lexer, i);
-          if (t == T_LPAREN || t == T_LBRACK || t == T_LCURLY)
-            depth++;
-          else if ((t == T_RPAREN || t == T_RBRACK || t == T_RCURLY) && depth)
-            depth--;
-          else if ((t == T_SLASH && !depth) || t == T_ENDCMD || t == T_STOP)
-            {
-              if (i > 0)
-                cmd->print.title = lex_next_representation (s->lexer, 0, i - 1);
-              break;
-            }
-        }
-
+      int start_ofs = lex_ofs (s->lexer);
       cmd->print.expression = matrix_parse_exp (s);
       if (!cmd->print.expression)
         goto error;
+      cmd->print.title = lex_ofs_representation (s->lexer, start_ofs,
+                                                 lex_ofs (s->lexer) - 1);
     }
 
   while (lex_match (s->lexer, T_SLASH))
@@ -7190,7 +7183,7 @@ matrix_write_parse (struct matrix_state *s)
     {
       char s[FMT_STRING_LEN_MAX + 1];
       fmt_to_string (write->format, s);
-      msg (SE, _("Format %s is too wide for %zu-byte matrix eleemnts."),
+      msg (SE, _("Format %s is too wide for %zu-byte matrix elements."),
            s, sizeof (double));
       goto error;
     }
@@ -7499,7 +7492,7 @@ matrix_get_execute__ (struct matrix_command *cmd, struct casereader *reader,
                   error = true;
                 }
             }
-          else if (var_is_num_missing (var, d, MV_USER))
+          else if (var_is_num_missing (var, d) == MV_USER)
             {
               if (get->user.treatment == MGET_RECODE)
                 d = get->user.substitute;
@@ -8222,7 +8215,7 @@ matrix_mget_commit_var (struct ccase **rows, size_t n_rows,
         {
           struct variable *var = dict_get_var (d, cs + x);
           double value = case_num (rows[y], var);
-          if (var_is_num_missing (var, value, MV_ANY))
+          if (var_is_num_missing (var, value))
             {
               n_missing++;
               value = 0.0;