Sindbad~EG File Manager
/* M. Beeson, for Mathpert.
Original date, June 1994.
modified 10.7.97
6.11.13 modified make_title for RIEMANNSUMS
12.1.14 modified line 123
6.23.24 modified make_title on integral_test graphs
6.30.24 modified make_title on RIEMANNSUMS to include an integral sign
9.4.24 modified make_title on PARAMETRIC to include the interval as third argument
9.5.25 also for POLAR_CIRCULAR
9.7.24 modified make_title on ODE2 to include g->parameter_interval
1.6.25 make_title should not set g->left and g->right. It only makes a title.
2.27.25 modified make_title on IMPROPER_INTEGRATION
make_title, for making titles for graphs
When there are parameters, we want to show the
parameter values; consider x^3 + ax; we want to avoid x^3 + 0.0 x
and x^3 + -1.0 x and x^2 + 1.0 x. This is solved by 'gsub', which
does the necessary simplification.
*/
#include <math.h>
#include <string.h>
#include "terms.h"
#include "defns.h"
#include "vaux.h"
#include "graphstr.h"
#include "constant.h"
#include "display.h"
#include "gsub.h"
#include "dispfunc.h" /* newatom */
#include "deval.h"
#include "probtype.h"
#include "wtitle.h"
#include "proverdl.h"
#include "arith.h"
#include "polyval.h"
#include "model.h"
#include "parser.h"
#include "mpdoc.h" /* PDOCDATA */
#include "activedoc.h"
#include "display1.h" /* get_anddisplay */
#include "pstring.h" /* log_term for debugging */
/*_______________________________________________________________*/
void make_title(graph *g, term *bterm)
/* Compute the title term and return it, bblocked, in bterm.
This is done in different ways depending on g->graphtype */
{
term titleterm,s;
char *ystr;
term yterm,xterm,zterm;
if(g->graphtype==POLAR || g->graphtype == POLAR_CIRCULAR)
{ ystr = g->rvariable;
yterm = MAKE_ATOM(newatom(ystr));
/* don't use make_atom_from_string, so as
not to use up space in varlist unnecessarily */
}
else
{ yterm = g->dependent_variable;
if(FUNCTOR(yterm) == 0 && ARITY(yterm) == 0)
{ /* g->dependent_variable hasn't been set,
e.g. on approximate integration types */
char c;
if(!contains(g->function,'y'))
yterm = MAKE_ATOM('y');
else if(!contains(g->function,'z'))
yterm = MAKE_ATOM('z');
else
{ for(c = 'w'; c >= 'a'; c--)
{ if(!contains(g->function,c))
{ yterm = MAKE_ATOM(c);
break;
/* g->function can't contain all 26 letters */
}
}
}
}
}
switch(g->graphtype)
{ case RELATION:
titleterm = g->function;
break;
case MC_SET:
titleterm = g->function;
break;
case MC_INEQ:
titleterm = g->function;
break;
case ORDINARY:
titleterm = equation(yterm,g->function);
break;
case POLAR: // fall through
case POLAR_CIRCULAR:
yterm = MAKE_ATOM(newatom(g->rvariable));
titleterm = and(equation(yterm,g->function),g->parameter_interval);
break;
case COMPLEX_CONTOUR:
{ unsigned f = FUNCTOR(g->function);
if(f==ABSFUNCTOR || f == REALPART || f == IMAGPART)
titleterm = g->function;
else
titleterm = re(g->function);
}
break;
case POLYROOT:
titleterm = g->function;
break;
case CONTOUR:
titleterm = g->function;
break;
case PARAMETRIC:
xterm = MAKE_ATOM(newatom(g->xvariable));
yterm = MAKE_ATOM(newatom(g->yvariable));
titleterm = and3(equation(xterm,g->xfunction),
equation(yterm,g->yfunction),
g->parameter_interval);
break;
case SPACECURVE: /* fall through */
case PARAMETRICSURFACE:
xterm = MAKE_ATOM(newatom(g->xvariable));
yterm = MAKE_ATOM(newatom(g->yvariable));
zterm = MAKE_ATOM(newatom(g->zvariable));
titleterm = and3(equation(xterm,g->xfunction),
equation(yterm,g->yfunction),
equation(zterm,g->zfunction)
);
break;
case POLARNONPARAMETRICSURFACE: /* fall through */
case NONPARAMETRICSURFACE:
zterm = MAKE_ATOM(newatom(g->zvariable));
titleterm = equation(zterm,g->zfunction);
break;
case RIEMANNSUMS:
case SIMPSONSRULE:
case TRAPEZOIDRULE:
if(g->whichgraph == 1)
{ titleterm = g->function;
// this code is never executed because graphs[1] has type ORDINARY_GRAPH
}
else
{ double z;
deval(g->xfunction,&z);
if(get_problemtype() == ADDSERIES || get_problemtype() == TESTCONVERGENCE)
{ // we're drawing a partial sum of an infinite series, as a graph-button document in _integral_test
term u,hi;
term lo = g->xfunction;
term *varlist = get_varlist();
term n = varlist[0]; // where it was created, and never moved.
deval(g->yfunction,&z); // g->right
hi = make_int((int) (z+ 0.000001));
subst(n,g->independent_variable,g->function,&u);
// using the original variable n for the formula to display
g->title = indexedsum(u,n,lo,hi);
titleterm = equation(g->title,make_double(g->area));
}
else /* still have g->whichgraph = 0 */
{
// ordinary Riemann-sums graph or improper integral
term integrand = g->function;
term x = g->independent_variable;
term lo = g->xfunction;
term hi = g->yfunction;
term A = definite_integral(integrand, x,lo,hi);
if(get_problemtype() == IMPROPER_INTEGRATION)
titleterm = ge(A,make_double(g->area));
else
titleterm = approxeq(A,make_double(g->area));
}
}
break;
case ODE: // fall through
case HDE:
case ODE2:
case ODESYSTEM:
// the title term should include the parameters
{
int nparams;
nparams = get_nparameters();
parameter *params = get_parameters();
term *vars = get_varlist();
titleterm = make_term(AND,nparams+2);
ARGREP(titleterm,0,g->function);
term y0;
int y0flag = 0;
for(int k = 0; k<nparams; k++)
{ double val = * (double *) params[k].addr;
int index = params[k].index;
char *textname = params[k].name;
// This has been filled, e.g., with "y'_0", which we can't use conveniently
term pname = vars[index];
char y = textname[0];
if(y == FUNCTOR(g->dependent_variable) && textname[1] == '0')
{
y0 = vars[index];
y0flag = 1;
}
else if(y0flag && y == FUNCTOR(g->dependent_variable))
{ int nprimes = (int) strlen(textname)-3;
pname = pr(y0,make_int(nprimes)); // e.g., y_0''
}
ARGREP(titleterm,k+1,equation(pname,make_double(val)));
}
if(FUNCTOR(g->parameter_interval))
ARGREP(titleterm,nparams+1,g->parameter_interval);
else
SETARITY(titleterm,nparams+1);
int oldand_display = get_anddisplay();
set_anddisplay(1); /* No brackets or bars */
bblock(titleterm,bterm);
set_anddisplay(oldand_display);
return; // don't do gsub for these problemtypes
}
default: /* ode problems get here */
titleterm = g->function; /* ode problems get here */
}
gsub(titleterm,&s);
bblock(s,bterm);
destroy_term(s);
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists