Commit bbd4e388 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

Fix many complex number comparisons to fix computation of complex matrix


Tue Aug 08 11:00:19 2006  Jiri (George) Lebl <jirka@5z.com>

	* src/calc.c, src/eval.c, src/funclib.c, src/matop.c:  Fix many
	  complex number comparisons to fix computation of complex matrix
	  determinants and other instances where gaussian elimination was
	  used.  Also for the polynomial functions and handling of booleans
	  and a few more.

	* src/genius.c: Add --exec option, follow gnu semantics for
	  the long options with arguments

	* src/geniustest.pl: Use --exec option instead of echo

	* src/geniustests.txt: Add tests for the complex number handling
	  fixes
parent 3d0e0aeb
Tue Aug 08 11:00:19 2006 Jiri (George) Lebl <jirka@5z.com>
* src/calc.c, src/eval.c, src/funclib.c, src/matop.c: Fix many
complex number comparisons to fix computation of complex matrix
determinants and other instances where gaussian elimination was
used. Also for the polynomial functions and handling of booleans
and a few more.
* src/genius.c: Add --exec option, follow gnu semantics for
the long options with arguments
* src/geniustest.pl: Use --exec option instead of echo
* src/geniustests.txt: Add tests for the complex number handling
fixes
Tue Aug 01 19:48:10 2006 Jiri (George) Lebl <jirka@5z.com>
* src/gnome-genius.c: use same geometry setup as gnome-terminal
......
/* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. */
/*$Id$*/
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
/*
......
......@@ -1175,7 +1175,7 @@ appendpolynomial (GelOutput *gelo, GelETree *n)
int i = index[0] + (index[1]*stride) + (index[2]*stride*stride);
int j;
if (n->poly.indexes[i] != NULL &&
mpw_sgn (n->poly.indexes[i]) != 0) {
! mpw_eql_ui (n->poly.indexes[i], 0)) {
char *p;
gboolean firstvar;
......
......@@ -2364,10 +2364,7 @@ gel_isnodetrue (GelETree *n, gboolean *bad_node)
case NULL_NODE:
return FALSE;
case VALUE_NODE:
if (mpw_sgn(n->val.value)!=0)
return TRUE;
else
return FALSE;
return ! mpw_eql_ui (n->val.value, 0);
case STRING_NODE:
if(n->str.str && *n->str.str)
return TRUE;
......@@ -4825,7 +4822,7 @@ iter_forloop (GelCtx *ctx, GelETree *n, gboolean *repushed)
iter_pop_stack(ctx);
return;
}
if G_UNLIKELY (by && mpw_sgn(by->val.value)==0) {
if G_UNLIKELY (by && mpw_eql_ui (by->val.value, 0)) {
gel_errorout (_("'for/sum/prod' loop increment can't be 0"));
iter_pop_stack(ctx);
return;
......
......@@ -239,7 +239,7 @@ IntegerFromBoolean_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
return NULL;
if (a[0]->type == VALUE_NODE)
i = (mpw_sgn(a[0]->val.value)!=0) ? 1 : 0;
i = mpw_eql_ui (a[0]->val.value, 0) ? 0 : 1;
else /* a->type == BOOL_NODE */
i = a[0]->bool_.bool_ ? 1 : 0;
......@@ -855,7 +855,7 @@ CountZeroColumns_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
if ( ! ( t == NULL ||
t->type == NULL_NODE ||
(t->type == VALUE_NODE &&
mpw_cmp_ui (t->val.value, 0) == 0))) {
mpw_eql_ui (t->val.value, 0)))) {
cnt++;
break;
}
......@@ -892,7 +892,7 @@ StripZeroColumns_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
if ( ! ( t == NULL ||
t->type == NULL_NODE ||
(t->type == VALUE_NODE &&
mpw_cmp_ui (t->val.value, 0) == 0))) {
mpw_eql_ui (t->val.value, 0)))) {
cols = g_slist_prepend (cols,
GINT_TO_POINTER (i));
cnt++;
......@@ -2909,7 +2909,7 @@ is_row_zero (GelMatrixW *m, int r)
if (node != NULL &&
(node->type != VALUE_NODE ||
/* FIXME: perhaps use some zero tolerance */
mpw_sgn (node->val.value) != 0)) {
! mpw_eql_ui (node->val.value, 0))) {
return FALSE;
}
}
......@@ -3367,7 +3367,7 @@ poly_cut_zeros(GelMatrixW *m)
int cutoff;
for(i=gel_matrixw_width(m)-1;i>=1;i--) {
GelETree *t = gel_matrixw_index(m,i,0);
if(mpw_sgn(t->val.value)!=0)
if ( ! mpw_eql_ui(t->val.value, 0))
break;
}
cutoff = i+1;
......@@ -3524,8 +3524,8 @@ MultiplyPoly_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
GelETree *l,*r,*nn;
l = gel_matrixw_index(m1,i,0);
r = gel_matrixw_index(m2,j,0);
if(mpw_sgn(l->val.value)==0 ||
mpw_sgn(r->val.value)==0)
if (mpw_eql_ui (l->val.value, 0) ||
mpw_eql_ui (r->val.value, 0))
continue;
mpw_mul(accu,l->val.value,r->val.value);
nn = gel_matrixw_set_index(mn,i+j,0);
......@@ -3692,7 +3692,7 @@ PolyToString_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
GelETree *n;
int i;
GString *gs;
int any = FALSE;
gboolean any = FALSE;
GelMatrixW *m;
char *var;
GelOutput *gelo;
......@@ -3725,25 +3725,38 @@ PolyToString_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
for(i=gel_matrixw_width(m)-1;i>=0;i--) {
GelETree *t;
t = gel_matrixw_index(m,i,0);
if(mpw_sgn(t->val.value)==0)
if (mpw_eql_ui (t->val.value, 0))
continue;
/*positive*/
if(mpw_sgn(t->val.value)>0) {
/*positive (or complex) */
if (mpw_is_complex (t->val.value) ||
mpw_sgn (t->val.value) > 0) {
if(any) g_string_append(gs," + ");
if(i==0)
gel_print_etree (gelo, t, FALSE);
else if(mpw_cmp_ui(t->val.value,1)!=0) {
gel_print_etree (gelo, t, FALSE);
g_string_append_c(gs,'*');
if (MPW_IS_COMPLEX (t->val.value)) {
g_string_append_c (gs, '(');
if (i==0) {
gel_print_etree (gelo, t, FALSE);
g_string_append_c (gs, ')');
} else if ( ! mpw_eql_ui(t->val.value,1)) {
gel_print_etree (gelo, t, FALSE);
g_string_append_c (gs, ')');
g_string_append_c(gs,'*');
}
} else {
if (i == 0) {
gel_print_etree (gelo, t, FALSE);
} else if ( ! mpw_eql_ui (t->val.value, 1)) {
gel_print_etree (gelo, t, FALSE);
g_string_append_c(gs,'*');
}
}
/*negative*/
} else {
if(any) g_string_append(gs," - ");
else g_string_append_c(gs,'-');
mpw_neg(t->val.value,t->val.value);
if(i==0)
if (i == 0) {
gel_print_etree (gelo, t, FALSE);
else if(mpw_cmp_ui(t->val.value,1)!=0) {
} else if ( ! mpw_eql_ui (t->val.value, 1)) {
gel_print_etree (gelo, t, FALSE);
g_string_append_c(gs,'*');
}
......@@ -3834,7 +3847,7 @@ PolyToFunction_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
for(i=gel_matrixw_width(m)-1;i>=0;i--) {
GelETree *t;
t = gel_matrixw_index(m,i,0);
if(mpw_sgn(t->val.value)==0)
if (mpw_eql_ui (t->val.value, 0))
continue;
if(!nn)
......@@ -4743,7 +4756,7 @@ set_ResultsAsFloats (GelETree * a)
if G_UNLIKELY ( ! check_argument_bool (&a, 0, "set_ResultsAsFloats"))
return NULL;
if (a->type == VALUE_NODE)
calcstate.results_as_floats = mpw_sgn(a->val.value)!=0;
calcstate.results_as_floats = ! mpw_eql_ui (a->val.value, 0);
else /* a->type == BOOL_NODE */
calcstate.results_as_floats = a->bool_.bool_;
if(statechange_hook)
......@@ -4762,7 +4775,7 @@ set_ScientificNotation (GelETree * a)
if G_UNLIKELY ( ! check_argument_bool (&a, 0, "set_ScientificNotation"))
return NULL;
if (a->type == VALUE_NODE)
calcstate.scientific_notation = mpw_sgn(a->val.value)!=0;
calcstate.scientific_notation = ! mpw_eql_ui (a->val.value, 0);
else /* a->type == BOOL_NODE */
calcstate.scientific_notation = a->bool_.bool_;
if(statechange_hook)
......@@ -4781,7 +4794,7 @@ set_FullExpressions (GelETree * a)
if G_UNLIKELY ( ! check_argument_bool (&a, 0, "set_FullExpressions"))
return NULL;
if (a->type == VALUE_NODE)
calcstate.full_expressions = mpw_sgn(a->val.value)!=0;
calcstate.full_expressions = ! mpw_eql_ui (a->val.value, 0);
else /* a->type == BOOL_NODE */
calcstate.full_expressions = a->bool_.bool_;
if(statechange_hook)
......@@ -4885,7 +4898,7 @@ set_MixedFractions (GelETree * a)
if G_UNLIKELY ( ! check_argument_bool (&a, 0, "set_MixedFractions"))
return NULL;
if (a->type == VALUE_NODE)
calcstate.mixed_fractions = mpw_sgn(a->val.value)!=0;
calcstate.mixed_fractions = ! mpw_eql_ui (a->val.value, 0);
else /* a->type == BOOL_NODE */
calcstate.mixed_fractions = a->bool_.bool_;
if(statechange_hook)
......
......@@ -198,6 +198,7 @@ main(int argc, char *argv[])
gboolean do_compile = FALSE;
gboolean do_gettext = FALSE;
gboolean be_quiet = FALSE;
char *exec = NULL;
genius_is_gui = FALSE;
......@@ -225,6 +226,15 @@ main(int argc, char *argv[])
val = 128;
}
curstate.float_prec = val;
} else if (strcmp (argv[i], "--precision")==0 && i+1 < argc) {
val = 0;
sscanf (argv[++i],"%d",&val);
if (val < 60 || val > 16384) {
g_printerr (_("%s should be between %d and %d, using %d"),
"--precision", 60, 16384, 128);
val = 128;
}
curstate.float_prec = val;
} else if(sscanf(argv[i],"--maxdigits=%d",&val)==1) {
if (val < 0 || val > 256) {
g_printerr (_("%s should be between %d and %d, using %d"),
......@@ -232,6 +242,15 @@ main(int argc, char *argv[])
val = 12;
}
curstate.max_digits = val;
} else if (strcmp (argv[i], "--maxdigits")==0 && i+1 < argc) {
val = -1;
sscanf (argv[++i],"%d",&val);
if (val < 0 || val > 256) {
g_printerr (_("%s should be between %d and %d, using %d"),
"--maxdigits", 0, 256, 12);
val = 12;
}
curstate.max_digits = val;
} else if(strcmp(argv[i],"--floatresult")==0)
curstate.results_as_floats = TRUE;
else if(strcmp(argv[i],"--nofloatresult")==0)
......@@ -251,13 +270,26 @@ main(int argc, char *argv[])
val = 5;
}
curstate.max_errors = val;
} else if (strcmp (argv[i], "--maxerrors")==0 && i+1 < argc) {
val = -1;
sscanf (argv[++i],"%d",&val);
if (val < 0) {
g_printerr (_("%s should be greater then or equal to %d, using %d"),
"--maxerrors", 0, 5);
val = 5;
}
curstate.max_errors = val;
} else if(strcmp(argv[i],"--mixed")==0)
curstate.mixed_fractions = TRUE;
else if(strcmp(argv[i],"--nomixed")==0)
curstate.mixed_fractions = FALSE;
else if(sscanf(argv[i],"--intoutbase=%d",&val)==1)
else if(sscanf(argv[i],"--intoutbase=%d",&val)==1) {
curstate.integer_output_base = val;
} else if (strcmp (argv[i], "--intoutbase")==0 && i+1 < argc) {
val = 10;
sscanf (argv[++i],"%d",&val);
curstate.integer_output_base = val;
else if(strcmp(argv[i],"--readline")==0)
} else if(strcmp(argv[i],"--readline")==0)
use_readline = TRUE;
else if(strcmp(argv[i],"--noreadline")==0)
use_readline = FALSE;
......@@ -273,7 +305,11 @@ main(int argc, char *argv[])
be_quiet = TRUE;
else if(strcmp(argv[i],"--noquiet")==0)
be_quiet = FALSE;
else if (strcmp (argv[i], "--version") == 0) {
else if (strncmp (argv[i], "--exec=", strlen ("--exec=")) == 0) {
exec = g_strdup ((argv[i])+strlen("--exec="));
} else if (strcmp (argv[i], "--exec") && i+1 < argc) {
exec = g_strdup (argv[++i]);
} else if (strcmp (argv[i], "--version") == 0) {
g_print (_("Genius %s\n"
"%s%s\n"),
VERSION,
......@@ -302,7 +338,8 @@ main(int argc, char *argv[])
"\t--[no]gettext \tDump help/error strings in fake .c file to\n"
"\t \tstdout (for use with gettext) [OFF]\n"
"\t--[no]quiet \tBe quiet during non-interactive mode,\n"
"\t \t(always on when compiling) [OFF]\n\n"),
"\t \t(always on when compiling) [OFF]\n"
"\t--exec=expr \tExecute an expression\n\n"),
VERSION);
if (strcmp (argv[i], "--help") != 0)
exit (1);
......@@ -311,6 +348,11 @@ main(int argc, char *argv[])
}
}
if (files != NULL && exec != NULL) {
g_printerr (_("Can't specify both an expression and files to execute on the command line"));
exit (1);
}
#if 0
{
/* FIXME: use this for option parsing,
......@@ -330,7 +372,7 @@ main(int argc, char *argv[])
if (do_compile || do_gettext)
be_quiet = TRUE;
inter = isatty(0) && !files && !(do_compile || do_gettext);
inter = isatty(0) && !files && !exec && !(do_compile || do_gettext);
/*interactive mode, print welcome message*/
if (inter) {
g_print (_("Genius %s\n"
......@@ -417,11 +459,15 @@ main(int argc, char *argv[])
gel_save_plugins ();
return 0;
}
} else if (exec != NULL) {
fp = NULL;
gel_push_file_info("expr",1);
} else {
fp = stdin;
gel_push_file_info(NULL,1);
}
gel_lexer_open(fp);
if (fp != NULL)
gel_lexer_open(fp);
if(inter && use_readline) {
init_inter();
}
......@@ -430,6 +476,13 @@ main(int argc, char *argv[])
rl_event_hook = nop;
if (exec != NULL) {
line_len_cache = -1;
gel_evalexp (exec, NULL, main_out, NULL, FALSE, NULL);
line_len_cache = -1;
goto after_exec;
}
for(;;) {
for(;;) {
if(inter && use_readline) /*use readline mode*/ {
......@@ -473,36 +526,19 @@ main(int argc, char *argv[])
}
} while(!fp && files);
if(!fp && !files) {
if (do_compile) {
gel_push_file_info(NULL,0);
gel_compile_all_user_funcs(stdout);
gel_pop_file_info();
/* if we have gotten errors then
signal by returning a 1 */
if(total_errors_printed)
return 1;
} else if (do_gettext) {
gel_push_file_info (NULL, 0);
gel_dump_strings_from_help (stdout);
gel_dump_strings_from_user_funcs (stdout);
gel_pop_file_info ();
/* if we have gotten errors then
signal by returning a 1 */
if (total_errors_printed)
return 1;
} else {
gel_save_plugins ();
}
return 0;
goto after_exec;
}
gel_lexer_open(fp);
} else
break;
}
after_exec:
gel_printout_infos ();
gel_lexer_close(fp);
if (fp != NULL)
gel_lexer_close(fp);
/*if(fp != stdin)
fclose(fp);*/
......
......@@ -28,7 +28,7 @@ while(<TESTS>) {
#something weird happens and the following modifies $1 and $2
#as well, I guess those can only be used from the last regexp
$command =~ s/'/'\\''/g;
open(GENIUS,"echo '$command' | ./genius $options |") ||
open(GENIUS,"./genius --exec='$command' $options |") ||
die "can't open pipe!";
if($rep=<GENIUS>) {
......
......@@ -234,7 +234,7 @@ if("AHA"=="AHA") then 1 else 0 1
if("AHA "=="AHA") then 1 else 0 0
not &d (not (&d))
3i>3i (3i>3i)
not 3i (not 3i)
not 3i false
if(3=="3")then 1 else 0 1
if(3=="3 ")then 1 else 0 0
IsNull(1) false
......@@ -251,7 +251,7 @@ IsNull(.) true
1' (1')
[1,2]*[3,4]' [11]
AddPoly([1,1,2],[0,1]) [1,2,2]
SubtractPoly([1,1,2],[0,1]) [1,0,2]
SubtractPoly([1,1,2],[0,1]) [1,0,2]
TrimPoly([1,1,0]) [1,1]
TrimPoly([0,0,0]) [0]
PolyToString([2,-1,2,3],"x") "3*x^3 + 2*x^2 - x + 2"
......@@ -263,6 +263,7 @@ IsPoly([0,1,2,&d]) false
PolyToString(MultiplyPoly([1,1],[1,1]),"x") "x^2 + 2*x + 1"
PolyToString(MultiplyPoly([-1,1],[1,1]),"x") "x^2 - 1"
f=PolyToFunction([3,1,1]);f(2) 9
f=PolyToFunction([3i,1i,1i]);f(2) 9i
IsFunction(`(x)=x+1) true
IsFunction(function(x)=x+1) true
IsFunction(1) false
......@@ -433,6 +434,7 @@ MixedFractions=0 ; 123 7/8 991/8
010 8
0100 64
8\100 64
8 \ 100 12 1/2
IntegerOutputBase=16 ; 256 0x100
IntegerOutputBase=9 ; 81 9\100
IntegerOutputBase=12 ; 11 12\b
......@@ -706,19 +708,27 @@ SymbolicDerivative(`(x)=1/x) (`(x)=(-1/(x^2)))
function f() = (for n=1 to 2 do (a=`[[1]]);a);f() `[[1]]
NullSpace ([1,0,0,2,4;0,0,1,-3,5]) [0,2,4;-1,0,0;0,-3,5;0,-1,0;0,0,-1]
A=[1,1,1,1;2,3,4,1;9,1,1,1];A*NullSpace(A)@(,1) [0;0;0]
A=[1,1i,1,1;2,3,4i,1;9,1,1,1i];A*NullSpace(A)@(,1) [0;0;0]
CountZeroColumns ([1]) 0
CountZeroColumns (null) 0
CountZeroColumns ([1,0,1]) 1
CountZeroColumns ([1,0,1;1,0,1]) 1
CountZeroColumns ([1i,0,1;1,0,1]) 1
CountZeroColumns ([1,0,1;0,0,0]) 1
CountZeroColumns ([1,0,0;0,0,0]) 2
StripZeroColumns ([1]) [1]
StripZeroColumns (null)+1 ((null)+1)
StripZeroColumns ([1,0,2]) [1,2]
StripZeroColumns ([1,0,2;3,0,4]) [1,2;3,4]
StripZeroColumns ([1,0,2i;3i,0,4]) [1,2i;3i,4]
StripZeroColumns ([1,0,2;0,0,0]) [1,2;0,0]
StripZeroColumns ([1,0,0;0,0,0]) [1;0]
NextCombination([1,2,3,4],6) [1,2,3,5]
NextCombination([1,2,3,6],6) [1,2,4,5]
NextCombination([3,4,5,6],6)+1 ((null)+1)
det ([1i,1i+3,5,6;4,0,8,6;8,1i,1i,1;1,2,3,4]) 56+176i
PolyToString([1i,2i,3i]) "(3i)*x^2 + (2i)*x + (1i)"
if 1i then 1 else 0 1
A=[1,2,3,4;1i,2,3i,4;1,1,1,1;1i,1i,1i,9];A^-1 * A == I(4) true
IntegerFromBoolean(1i) 1
load "longtest.gel" true
......@@ -275,7 +275,7 @@ div_row (GelCtx *ctx, GelMatrixW *m, int row, mpw_t div)
int i;
gboolean ret = TRUE;
if(mpw_cmp_ui(div,1)==0)
if (mpw_eql_ui (div, 1))
return TRUE;
gel_matrixw_make_private(m);
......@@ -350,7 +350,8 @@ gel_value_matrix_gauss (GelCtx *ctx, GelMatrixW *m, gboolean reduce, gboolean
for(i=0;i<gel_matrixw_width(m) && d<gel_matrixw_height(m);i++) {
for(j=d;j<gel_matrixw_height(m);j++) {
GelETree *t = gel_matrixw_set_index(m,i,j);
if(t && mpw_sgn(t->val.value)!=0)
if (t != NULL &&
! mpw_eql_ui (t->val.value, 0))
break;
}
if(j==gel_matrixw_height(m)) {
......@@ -375,7 +376,8 @@ gel_value_matrix_gauss (GelCtx *ctx, GelMatrixW *m, gboolean reduce, gboolean
GelETree *t = gel_matrixw_set_index(m,i,j);
/* Assume t is already reduced mod ctx->modulo
* if appropriate */
if(t && mpw_sgn(t->val.value)!=0) {
if (t != NULL &&
! mpw_eql_ui (t->val.value, 0)) {
mpw_div(tmp,t->val.value,piv->val.value);
if ( ! mul_sub_row (ctx, m, d, tmp, j) &&
stopsing) {
......@@ -402,7 +404,8 @@ gel_value_matrix_gauss (GelCtx *ctx, GelMatrixW *m, gboolean reduce, gboolean
if(reduce) {
for(j=0;j<d;j++) {
GelETree *t = gel_matrixw_set_index(m,i,j);
if(t && mpw_sgn(t->val.value)!=0) {
if (t != NULL &&
! mpw_eql_ui (t->val.value, 0)) {
mpw_div(tmp,t->val.value,piv->val.value);
if ( ! mul_sub_row (ctx, m, d, tmp, j) &&
stopsing) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment