PREP 2014 Question Authoring - Archived

debugging graphics and general

debugging graphics and general

by Joel Trussell -
Number of replies: 4
I"m trying to use dynamic graphics to display a series of graphs - real and imaging parts of a discrete complex function. I need to find the min and max of the solutions in order to set the limits on the graphs. I think I have this down using min(@vector) and max(@vector). I"m having difficulty on (at least) two points plotting the discrete points, I try 
$point1[0] = closed_circle(n_vec[0],$alpha_re[0], 'red');
which give a syntax error I cannot find. The vectors n_vec and alpha_re are defined and used elsewhere. 

commenting those lines out, I get an error at line 137
a divide by zero. I thought this would be problems with the computed limits. But I'm having difficulty displaying the limits, since program bombs. How do I find the offending values? 

Thanks

DOCUMENT();        # This should be the first executable line in the problem.

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"AnswerFormatHelp.pl",
"PGgraphmacros.pl",
"unionTables.pl",
"PGanswermacros.pl",
"PGchoicemacros.pl",
 "PGgraphmacros.pl",
  "extraAnswerEvaluators.pl",
 "parserCustomization.pl",
"PGcourse.pl"
);

TEXT(beginproblem());

$refreshCachedImages = 1;

Context("Complex");
Context()->variables->are(
n=>"Real",
t=>"Real"
);
Context()->flags->set(
  tolerance => 0.001,
  tolType => "absolute",
);


$Tover2 = random(5,10,1);
$T = 2*$Tover2;
$d0 = random(2,$T-4,1);
$t0 = -$Tover2 + $d0;
$d1 = random(1, $Tover2-$t0-2, 1);
$t1 = $t0 + $d1;
$d2 = random(1,$Tover2-$t1-1,1);
$t2 = $t1 + $d2;

$w0 = 2*pi/$T;

$a1 = non_zero_random(-6, 6, 1);
do {$a2 = non_zero_random(-6, 6, 1);} until ($a2 != $a1);

$FSeries = Formula("(1/$T)*(i*($a1/($w0*n))*(exp((-1)*i*$w0*$t1*n) - exp((-1)*i*$w0*$t0*n)) + i*($a2/($w0*n))*(exp((-1)*i*$w0*$t2*n) - exp((-1)*i*$w0*$t1*n)) ) ")->reduce;

$N = 6;
$indx = -1;
for ($k=-$N, $k<= $N,$k++) {
    $indx++;
    if ($k == 0) {$alpha[$indx]  = Compute(($d1*$a1 + $d2*$a2)/$T); }
    else {
      $alpha[$indx] = $FSeries -> eval(n=>$k);
    };
   $alpha_mag[$indx] = abs($alpha[$indx] );
   $alpha_ph[$indx] = arg($alpha[$indx] );
   $alpha_re[$indx] = Re($alpha[$indx] );
   $alpha_im[$indx] = Im($alpha[$indx] );
   $n_vec[$indx] = $k;
};

#$alpha0m = Compute(abs($alpha0));
#$alpha0p = Compute(0);
#if ($alpha0 < 0) {$alpha0p = pi;}
# check back for adding pi for correct quadrant


#$f_approx = Formula(" $alpha0 + 2*$alphap1m*cos($w0*t + $alphap1p) + 2*$alphap2m*cos($w0*2*t + $alphap2p) ")->reduce;

### generate graphics

$a = random(1,9,1);
$b = random(2,1,9);   
$c = random(2,1,9);
$n_min = -($N+1);
$n_max = ($N+1);    
$grid_n = $n_max - $n_min;          

$Fmag_min = Compute(min(@alpha_mag)); 
$Fph_min = (-1)*pi; 
$Fmag_max = Compute(max(@alpha_mag)); 
$Fph_max = pi; 
$Fre_min = Compute(min(@alpha_re)); 
$Fim_min = Compute(min(@alpha_im)); 
$Fre_max = Compute(max(@alpha_re)); 
$Fim_max = Compute(max(@alpha_im)); 
$grid_mag = $Fmag_max - $Fmag_min;   # limits are same for real and imag parts
$grid_ph = $Fph_max - $Fph_min;   # limits are same for real and imag parts
$grid_re = $Fre_max - $Fre_min;   # limits are same for real and imag parts
$grid_im = $Fim_max - $Fim_min;   # limits are same for real and imag parts


#$orig = image(insertGraph($gr),width => 400,height => 300,tex_size => 600);

# generate functions


# insert functions into graph
for ($j = 0; $j <=5; $j++) {
$graph_re[$j] = init_graph($n_min,$Fre_min,$n_max,$Fre_max,'axes'=>[0,0],'grid'=>[$grid_n,$grid_re] );
$graph_im[$j] = init_graph($n_min,$Fim_min,$n_max,$Fim_max,'axes'=>[0,0],'grid'=>[$grid_n,$grid_im] );
};

# set labels in graphs
for ($j = 0; $j <=5; $j++) {
$graph_re[$j]->lb('reset');
$graph_re[$j]->lb(new Label(-0.5,0,0,'black','right','middle'));
$graph_re[$j]->lb(new Label(-0.5,($Fre_max-1),($Fre_max-1),'black','right','middle'));
for ($i = 0; $i <= ($n_max-1); $i++) { if ($i != 0) {
    $graph_re[$j]->lb(new Label($i,-.5,$i,'black','center','top')) }};
$graph_re[$j]->lb(new Label(-.5,($Fre_max/2),"Fre",'black','right','top'));
$graph_re[$j]->lb(new Label(($n_max/2),-0.5,"n",'black','right','bottom'));

#plot_functions( $graph_re[$j], $real[$j]);
#$point1[0] = closed_circle(n_vec[0],$alpha_re[0], 'red');
#$point1[1] = closed_circle(n_vec[1],$alpha_re[1], 'red');
$point1[0] = closed_circle(-1,1, 'red');
$point1[1] = closed_circle(1,2, 'red');

$graph_re[$j] -> stamps($point1[0],$point1[1]);
$fig_re[$j] = image(insertGraph($graph_re[$j]),width => 240,height => 180,tex_size => 200); 

$graph_im[$j]->lb('reset');
$graph_im[$j]->lb(new Label(-0.5,0,0,'black','right','middle'));
$graph_im[$j]->lb(new Label(-0.5,($Fim_max-1),($Fim_max-1),'black','right','middle'));
for ($i = 0; $i <= ($w_max-1); $i++) { if ($i != 0) {
    $graph_im[$j]->lb(new Label($i,-.5,$i,'black','center','top')) }};
$graph_im[$j]->lb(new Label(-.5,($Fim_max/2),"Im(F)",'black','right','top'));
$graph_im[$j]->lb(new Label(($n_max/2),-0.5,"n",'black','right','bottom'));
#plot_functions( $graph_im[$j], $imag[$j]);

#$point2[0] = closed_circle(n_vec[0],$alpha_im[0], 'blue');
#$point2[1] = closed_circle(n_vec[1],$alpha_im[1], 'blue');
$point1[0] = closed_circle(-1,1, 'red');
$point1[1] = closed_circle(1,2, 'red');
$graph_im[$j] -> stamps($point2[0],$point2[1]);

$fig_im[$j] = image(insertGraph($graph_im[$j]),width => 240,height => 180,tex_size => 200); 

};



$mc = new_multiple_choice();
$mc->qa('Sketch  accurate graphs of the real and imaginary parts of this function, \( Real(F(n)) \) and \( Imag(F(n) )\) , for integers \( n \in [-$N, $N] \).  Which (if any) of the graphs below matches the graph you drew?','Real $fig_re[0]     Imag $fig_im[0] $BR $BITALIC(click on image to enlarge)$EITALIC ');
$mc->extra('Real $fig_re[1]    Imag  $fig_im[1] $BR $BITALIC(click on image to enlarge)$EITALIC',
'Real $fig_re[2]    Imag $fig_im[2] $BR $BITALIC(click on image to enlarge)$EITALIC',
'Real $fig_re[3]     Imag $fig_im[3] $BR $BITALIC(click on image to enlarge)$EITALIC',
'Real $fig_re[4]     Imag $fig_im[4] $BR $BITALIC(click on image to enlarge)$EITALIC',
'Real $fig_re[5]     Imag $fig_im[5]$BR $BITALIC(click on image to enlarge)$EITALIC');

$mc->makeLast('None of the above');


Context()->texStrings;
BEGIN_TEXT
Graphing discrete  complex functions, e.g., Fourier series

$PAR
Consider the periodic function with period \( $T \) given by
$BR
\[ f(t) = \left\lbrace \begin{array}{ l l } 0 & \mbox{ if } -$Tover2 \leq t < $t0 \\ $a1 & \mbox{ if } $t0 \leq t < $t1 \\ 
$a2 & \mbox{ if } $t1 \leq t < $t2 \\ 
0 & \mbox{ if } $t2 \leq t < $Tover2. \end{array} \right. \]


$PAR
Find and plot the first $N coefficients of the exponential Fourier Series for \( f(t) \), i.e., \( F(n) \) for \( n = -$N, ... 0, ... $N.\)

$BR
\{ $mc->print_q() \} $BR
\{ $mc->print_a() \}

END_TEXT
Context()->normalStrings;

ANS(radio_cmp($mc->correct_ans));
## force a refresh of the image after changes





ENDDOCUMENT();        # This should be the last executable line in the problem.
 
In reply to Joel Trussell

Re: debugging graphics and general

by Davide Cervone -
You need $n_vec[...] not just n_vec.
In reply to Joel Trussell

Re: debugging graphics and general

by Davide Cervone -
Line 360 of WWPlot.pl is
        int( ($ymax - $y)*${$self->size}[1]/($ymax-$ymin) );
which suggest that $ymax and $ymin are the same. I'd look at the values you are passing for the range of y values and see that they really make sense. Try printing them out and see if they are really different.
In reply to Davide Cervone

Re: debugging graphics and general

by Joel Trussell -
I kinda figured that when I wrote 
I thought this would be problems with the computed limits. But I'm having difficulty displaying the limits, since program bombs. How do I find the offending values? 

I found the problems  but in order to get the program to allow printing the various values, I had to comment out a lot of stuff that was after the offending line along with the line the call inserting the image. 

Is there a better/more efficient way to print the values before the point where the program aborts? 

Is there a way to use an editor that would make the debugging process less onerous? I could use a standard editor copying and pasting the new code to the webwork editor is the only way I'd know to run the modified code. 

thanks