[system] / trunk / pg / macros / PGmatrixmacros.pl Repository:
ViewVC logotype

View of /trunk/pg/macros/PGmatrixmacros.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1121 - (download) (as text) (annotate)
Wed Jun 11 14:47:59 2003 UTC (16 years, 8 months ago) by lr003k
File size: 18579 byte(s)
I removed the subroutine answer_matrix since it really belongs in basic macros with the other answer blank methods.

    1 #!/usr/local/bin/webwork-perl
    2 
    3 ###########
    4 #use Carp;
    5 
    6 =head1 NAME
    7 
    8   Matrix macros for the PG language
    9 
   10 =head1 SYNPOSIS
   11 
   12 
   13 
   14 =head1 DESCRIPTION
   15 
   16 Almost all of the macros in the file are very rough at best.  The most useful is display_matrix.
   17 Many of the other macros work with vectors and matrices stored as anonymous arrays.
   18 
   19 Frequently it may be
   20 more useful to use the Matrix objects defined RealMatrix.pm and Matrix.pm and the constructs listed there.
   21 
   22 
   23 =cut
   24 
   25 BEGIN {
   26   be_strict();
   27 }
   28 
   29 sub _PGmatrixmacros_init {
   30 }
   31 
   32 # this subroutine zero_check is not very well designed below -- if it is used much it should receive
   33 # more work -- particularly for checking relative tolerance.  More work needs to be done if this is
   34 # actually used.
   35 
   36 sub zero_check{
   37     my $array = shift;
   38     my %options = @_;
   39   my $num = @$array;
   40   my $i;
   41   my $max = 0; my $mm;
   42   for ($i=0; $i< $num; $i++) {
   43     $mm = $array->[$i] ;
   44     $max = abs($mm) if abs($mm) > $max;
   45   }
   46     my $tol = $options{tol};
   47     $tol = 0.01*$options{reltol}*$options{avg} if defined($options{reltol}) and defined $options{avg};
   48     $tol = .000001 unless defined($tol);
   49   ($max <$tol) ? 1: 0;       # 1 if the array is close to zero;
   50 }
   51 sub vec_dot{
   52   my $vec1 = shift;
   53   my $vec2 = shift;
   54   warn "vectors must have the same length" unless @$vec1 == @$vec2;  # the vectors must have the same length.
   55   my @vec1=@$vec1;
   56   my @vec2=@$vec2;
   57   my $sum = 0;
   58 
   59   while(@vec1) {
   60     $sum += shift(@vec1)*shift(@vec2);
   61   }
   62   $sum;
   63 }
   64 sub proj_vec {
   65   my $vec = shift;
   66   warn "First input must be a column matrix" unless ref($vec) eq 'Matrix' and ${$vec->dim()}[1] == 1;
   67   my $matrix = shift;    # the matrix represents a set of vectors spanning the linear space
   68                          # onto which we want to project the vector.
   69   warn "Second input must be a matrix" unless ref($matrix) eq 'Matrix' and ${$matrix->dim()}[1] == ${$vec->dim()}[0];
   70   $matrix * transpose($matrix) * $vec;
   71 }
   72 
   73 sub vec_cmp{    #check to see that the submitted vector is a non-zero multiple of the correct vector
   74     my $correct_vector = shift;
   75     my %options = @_;
   76   my $ans_eval = sub {
   77     my $in =  shift @_;
   78 
   79     my $ans_hash = new AnswerHash;
   80     my @in = split("\0",$in);
   81     my @correct_vector=@$correct_vector;
   82     $ans_hash->{student_ans} = "( " . join(", ", @in ) . " )";
   83     $ans_hash->{correct_ans} = "( " . join(", ", @correct_vector ) . " )";
   84 
   85     return($ans_hash) unless @$correct_vector == @in;  # make sure the vectors are the same dimension
   86 
   87     my $correct_length = vec_dot($correct_vector,$correct_vector);
   88     my $in_length = vec_dot(\@in,\@in);
   89     return($ans_hash) if $in_length == 0;
   90 
   91     if (defined($correct_length) and $correct_length != 0) {
   92       my $constant = vec_dot($correct_vector,\@in)/$correct_length;
   93       my @difference = ();
   94       for(my $i=0; $i < @correct_vector; $i++ ) {
   95         $difference[$i]=$constant*$correct_vector[$i] - $in[$i];
   96       }
   97       $ans_hash->{score} = zero_check(\@difference);
   98 
   99     } else {
  100       $ans_hash->{score} = 1 if vec_dot(\@in,\@in) == 0;
  101     }
  102     $ans_hash;
  103 
  104     };
  105 
  106     $ans_eval;
  107 }
  108 
  109 ############
  110 
  111 =head4  display_matrix
  112 
  113     Usage   \{ display_matrix( [ [1, '\(\sin x\)'], [ans_rule(5), 6] ]) \}
  114             \{ display_matrix($A, align=>'crvl') \}
  115             \[ \{   display_matrix_mm($A)  \} \]
  116             \[ \{ display_matrix_mm([ [1, 3], [4, 6] ])  \} \]
  117 
  118     display_matrix produces a matrix for display purposes.  It checks whether
  119     it is producing LaTeX output, or if it is displaying on a web page in one
  120     of the various modes.  The input can either be of type Matrix, or a
  121     reference to an array.
  122 
  123     Entries can be numbers, bits of math mode, or answer boxes.
  124 
  125     display_matrix_mm functions similarly, except that it should be inside
  126     math mode.  display_matrix_mm cannot contain answer boxes in its entries.
  127     Entries to display_matrix_mm should assume that they are already in
  128     math mode.
  129 
  130     Both functions take an optional alignment string, similar to ones in
  131     LaTeX tabulars and arrays.  Here c for centered columns, l for left
  132     flushed columns, and r for right flushed columns.
  133 
  134     The alignment string can also specify vertical rules to be placed in the
  135     matrix.  Here s or | denote a solid line, d is a dashed line, and v
  136     requests the default vertical line.  This can be set on a system-wide
  137     or course-wide basis via the variable $defaultDisplayMatrixStyle, and
  138     it can default to solid, dashed, or no vertical line (n for none).
  139 
  140     The matrix has left and right delimiters also specified by
  141     $defaultDisplayMatrixStyle.  They can be parentheses, square brackets,
  142     braces, vertical bars, or none.  The default can be overridden in
  143     an individual problem with optional arguments such as left=>"|", or
  144     right=>"]".
  145 
  146 
  147 =cut
  148 
  149 
  150 sub display_matrix_mm{    # will display a matrix in tex format.
  151                        # the matrix can be either of type array or type 'Matrix'
  152   return display_matrix(@_, 'force_tex'=>1);
  153 }
  154 
  155 sub display_matrix_math_mode {
  156   return display_matrix_mm(@_);
  157 }
  158 
  159 sub display_matrix {
  160   my $ra_matrix = shift;
  161   my %opts = @_;
  162   # Now a global variable?
  163   my $styleParams = defined($main::defaultDisplayMatrixStyle) ?
  164     $main::defaultDisplayMatrixStyle : "(s)";
  165 
  166   set_default_options(\%opts,
  167                       '_filter_name' => 'displaymat',
  168                       'force_tex' => 0,
  169                       'left' => substr($styleParams,0,1),
  170                       'right' => substr($styleParams,2,1),
  171                       'midrule' => substr($styleParams,1,1),
  172                       'allow_unknown_options'=> 1);
  173 
  174   my ($numRows, $numCols, @myRows);
  175 
  176   if (ref($ra_matrix) eq 'Matrix' )  {
  177     ($numRows, $numCols) = $ra_matrix->dim();
  178     for( my $i=0; $i<$numRows; $i++) {
  179       $myRows[$i] = [];
  180       for (my $j=0; $j<$numCols; $j++) {
  181         my $entry = $ra_matrix->element($i+1,$j+1);
  182         $entry = "#" unless defined($entry);
  183         push @{ $myRows[$i] },  $entry;
  184       }
  185     }
  186   } else { # matrix is input at [ [1,2,3],[4,5,6]]
  187     $numCols = 0;
  188     @myRows = @{$ra_matrix};
  189     $numRows = scalar(@myRows); # counts horizontal rules too
  190     my $tmp;
  191     for $tmp (@myRows) {
  192       if($tmp ne 'hline') {
  193         my @arow = @{$tmp};
  194         $numCols= scalar(@arow);   #number of columns in table
  195         last;
  196       }
  197     }
  198   }
  199   my $out;
  200   my $j;
  201   my $alignString=''; # alignment as a string for dvi/pdf
  202   my $alignList;      # alignment as a list
  203 
  204   if(defined($opts{'align'})) {
  205     $alignString= $opts{'align'};
  206     $alignString =~ s/v/$opts{'midrule'}/g;
  207     $alignString =~ tr/s/|/; # Treat "s" as "|"
  208     $alignString =~ tr/n//;  # Remove "n" altogether
  209     @$alignList = split //, $alignString;
  210   } else {
  211     for($j=0; $j<$numCols; $j++) {
  212       $alignList->[$j] = "c";
  213       $alignString .= "c";
  214     }
  215   }
  216 
  217   $out .= dm_begin_matrix($alignString, %opts);
  218   $out .= dm_mat_left($numRows, %opts);
  219   # vertical lines put in with first row
  220   $j = shift @myRows;
  221   $out .= dm_mat_row($j, $alignList, %opts, 'isfirst'=>$numRows);
  222   for $j (@myRows) {
  223     $out .= dm_mat_row($j, $alignList, %opts, 'isfirst'=>0);
  224   }
  225   $out .= dm_mat_right($numRows, %opts);
  226   $out .= dm_end_matrix(%opts);
  227   $out;
  228 }
  229 
  230 sub dm_begin_matrix {
  231   my ($aligns)=shift;   #alignments of columns in table
  232   my %opts = @_;
  233   my $out = "";
  234   if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) {
  235 #   $out .= "\n";
  236     # This should be doable by regexp, but it wasn't working for me
  237     my ($j, @tmp);
  238     @tmp = split //, $aligns;
  239     $aligns='';
  240     for $j (@tmp) {
  241       # I still can't get an @ expression sent to TeX, so plain
  242       # vertical line
  243       $aligns .= ($j eq "d") ? '|' : $j;
  244     }
  245     $out .= $opts{'force_tex'} ? '' : '\(';
  246     $out .= '\displaystyle\left'.$opts{'left'}."\\begin{array}{$aligns} \n";
  247     }
  248   elsif ($main::displayMode eq 'Latex2HTML') {
  249     $out .= "\n\\begin{rawhtml} <TABLE  BORDER=0>\n\\end{rawhtml}";
  250     }
  251   elsif ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth' || $main::displayMode eq 'HTML_dpng' || $main::displayMode eq 'HTML_img') {
  252     $out .= "<TABLE BORDER=0>\n"
  253   }
  254   else {
  255     $out = "Error: dm_begin_matrix: Unknown displayMode: $main::displayMode.\n";
  256     }
  257   $out;
  258 }
  259 
  260 
  261 sub dm_mat_left {
  262   my $numrows = shift;
  263   my %opts = @_;
  264   if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) {
  265     return "";
  266   }
  267   my $out='';
  268   my $j;
  269   my ($brh, $erh) = ("",""); # Start and end raw html
  270   if($main::displayMode eq 'Latex2HTML') {
  271     $brh = "\\begin{rawhtml}";
  272     $erh = "\\end{rawhtml}";
  273   }
  274 
  275   if(($main::displayMode eq 'HTML_dpng') || $main::displayMode eq 'HTML_img' || ($main::displayMode eq 'Latex2HTML')) {
  276     $out .= "$brh<tr valign=\"center\"><td nowrap=\"nowrap\" align=\"left\">$erh";
  277     $out .= dm_image_delimeter($numrows, $opts{'left'});
  278     $out .= "$brh<td><table border=0  cellspacing=5>\n$erh";
  279     return $out;
  280   }
  281   # Mode is now tth
  282 
  283   $out .= dm_tth_delimeter($numrows, $opts{'left'});
  284   $out .= "<td><table border=0  cellspacing=5>\n";
  285   return $out;
  286 }
  287 
  288 sub dm_mat_right {
  289   my $numrows = shift;
  290   my %opts = @_;
  291   my $out='';
  292   my $j;
  293 
  294   if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) {
  295     return "";
  296   }
  297 
  298   if(($main::displayMode eq 'HTML_dpng') ||$main::displayMode eq 'HTML_img'|| ($main::displayMode eq 'Latex2HTML')) {
  299     if($main::displayMode eq 'Latex2HTML') { $out .= '\begin{rawhtml}'; }
  300     $out .= "</table><td nowrap=\"nowrap\" align=\"right\">";
  301     if($main::displayMode eq 'Latex2HTML') { $out .= '\end{rawhtml}'; }
  302 
  303 #   $out .= "<img alt=\"(\" src = \"".
  304 #     "/webwork_system_html/images"."/right$numrows.png\" >";
  305     $out.= dm_image_delimeter($numrows, $opts{'right'});
  306     return $out;
  307   }
  308 
  309   $out .= "</table>";
  310 
  311   $out .= dm_tth_delimeter($numrows, $opts{'right'});
  312   return $out;
  313 }
  314 
  315 sub dm_end_matrix {
  316   my %opts = @_;
  317 
  318   my $out = "";
  319   if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) {
  320     $out .= "\n\\end{array}\\right$opts{right}";
  321     $out .= $opts{'force_tex'} ? '' : "\\) ";
  322     }
  323   elsif ($main::displayMode eq 'Latex2HTML') {
  324     $out .= "\n\\begin{rawhtml} </TABLE >\n\\end{rawhtml}";
  325     }
  326   elsif ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth' || $main::displayMode eq 'HTML_dpng'||$main::displayMode eq 'HTML_img') {
  327     $out .= "</TABLE>\n";
  328     }
  329   else {
  330     $out = "Error: PGmatrixmacros: dm_end_matrix: Unknown displayMode: $main::displayMode.\n";
  331     }
  332   $out;
  333 }
  334 
  335 # Make an image of a big delimiter for a matrix
  336 sub dm_image_delimeter {
  337   my $numRows = shift;
  338   my $char = shift;
  339   my ($out, $j);
  340 
  341   if($char eq ".") {return("");}
  342   if($char eq "d") { # special treatment for dashed lines
  343     $out='\(\vbox to '.($numRows*1.7).'\baselineskip ';
  344     $out .='{\cleaders\hbox{\vbox{\hrule width0pt height3pt depth0pt';
  345     $out .='\hrule width0.3pt height6pt depth0pt';
  346     $out .='\hrule width0pt height3pt depth0pt}}\vfil}\)';
  347     return($out);
  348   }
  349   if($char eq "|") {
  350     $out='\(\vbox to '.($numRows*1.4).'\baselineskip ';
  351     $out .='{\cleaders\vrule width0.3pt';
  352     $out .='\vfil}\)';
  353     return($out);
  354   }
  355   if($char eq "{") {$char = '\lbrace';}
  356   if($char eq "}") {$char = '\rbrace';}
  357   $out .= '\(\setlength{\arraycolsep}{0in}\left.\begin{array}{c}';
  358   for($j=0;$j<=$numRows;$j++)  { $out .= '\! \\\\'; }
  359   $out .= '\end{array}\right'.$char.'\)';
  360   return($out);
  361 }
  362 
  363 # Basically uses a table of special characters and simple
  364 # recipe to produce big delimeters a la tth mode
  365 sub dm_tth_delimeter {
  366   my $numRows = shift;
  367   my $char = shift;
  368 
  369   if($char eq ".") { return("");}
  370   my ($top, $mid, $bot, $extra);
  371   my ($j, $out);
  372 
  373   if($char eq "(") { ($top, $mid, $bot, $extra) = ('','','','');}
  374   elsif($char eq ")") { ($top, $mid, $bot, $extra) = ('','','','');}
  375   elsif($char eq "|") { ($top, $mid, $bot, $extra) = ('','','','');}
  376   elsif($char eq "[") { ($top, $mid, $bot, $extra) = ('','','','');}
  377   elsif($char eq "]") { ($top, $mid, $bot, $extra) = ('','','','');}
  378   elsif($char eq "{") { ($top, $mid, $bot, $extra) = ('','','','');}
  379   elsif($char eq "}") { ($top, $mid, $bot, $extra) = ('','','','');}
  380   else { warn "Unknown delimiter in dm_tth_delimeter";}
  381 
  382   $out = '<td nowrap="nowrap" align="left"><font face="symbol">';
  383   $out .= "$top<br />";
  384   for($j=1;$j<$numRows; $j++) {
  385     $out .= "$mid<br />";
  386   }
  387   $out .= "$extra<br />";
  388   for($j=1;$j<$numRows; $j++) {
  389     $out .= "$mid<br />";
  390   }
  391   $out .= "$bot</font></td>\n";
  392   return $out;
  393 }
  394 
  395 # Make a row for the matrix
  396 sub dm_mat_row {
  397   my $elements = shift;
  398   my $tmp = shift;
  399   my @align =  @{$tmp} ;
  400   my %opts = @_;
  401   my @elements = @{$elements};
  402   my $out = "";
  403   my ($brh, $erh) = ("",""); # Start and end raw html
  404   if($main::displayMode eq 'Latex2HTML') {
  405     $brh = "\\begin{rawhtml}";
  406     $erh = "\\end{rawhtml}";
  407   }
  408   if ($main::displayMode eq 'TeX' or $opts{'force_tex'}) {
  409     while (@elements) {
  410       $out .= shift(@elements) . " &";
  411       }
  412      chop($out); # remove last &
  413      $out .= "\\cr  \n";
  414      # carriage returns must be added manually for tex
  415     }   elsif ($main::displayMode eq 'HTML' || $main::displayMode eq 'HTML_tth'
  416          || $main::displayMode eq 'HTML_dpng'
  417          || $main::displayMode eq 'HTML_img'
  418          || $main::displayMode eq 'Latex2HTML') {
  419     $out .=  "$brh\n<TR>\n$erh";
  420     while (@elements) {
  421       my $myalign;
  422       $myalign = shift @align;
  423       if($myalign eq "|" or $myalign eq "d") {
  424         if($opts{'isfirst'} && $main::displayMode ne 'HTML_tth') {
  425           $out .= $brh.'<td rowspan="'.$opts{'isfirst'}.'">'.$erh;
  426           $out .= dm_image_delimeter($opts{'isfirst'}-1, $myalign);
  427         } elsif($main::displayMode eq 'HTML_tth') {
  428           if($myalign eq "d") { # dashed line in tth mode
  429             $out .= '<td> | </td>';
  430           } elsif($opts{'isfirst'}) { # solid line in tth mode
  431             $out .= '<td rowspan="'.$opts{'isfirst'}.'"<table border="0"><tr>';
  432             $out .= dm_tth_delimeter($opts{'isfirst'}-1, "|");
  433             $out .= '</td></tr></table>';
  434           }
  435         }
  436       } else {
  437         if($myalign eq "c") { $myalign = "center";}
  438         if($myalign eq "l") { $myalign = "left";}
  439         if($myalign eq "r") { $myalign = "right";}
  440         $out .= "$brh<TD nowrap=\"nowrap\" align=\"$myalign\">$erh" . shift(@elements) . "$brh</TD>$erh";
  441       }
  442     }
  443     $out .= "$brh\n</TR>\n$erh";
  444   }
  445   else {
  446     $out = "Error: dm_mat_row: Unknown displayMode: $main::displayMode.\n";
  447     }
  448   $out;
  449 }
  450 
  451 =head4  mbox
  452 
  453     Usage \{ mbox(thing1, thing2, thing3) \}
  454           \{ mbox([thing1, thing2, thing3], valign=>'top') \}
  455 
  456     mbox takes a list of constructs, such as strings, or outputs of
  457     display_matrix, and puts them together on a line.  Without mbox, the
  458     output of display_matrix would always start a new line.
  459 
  460     The inputs can be just listed, or given as a reference to an array.
  461     With the latter, optional arguments can be given.
  462 
  463     Optional arguments are allowbreaks=>'yes' to allow line breaks in TeX
  464     output; and valign which sets vertical alignment on web page output.
  465 
  466 =cut
  467 
  468 sub mbox {
  469   my $inList = shift;
  470   my %opts;
  471   if(ref($inList) eq 'ARRAY') {
  472     %opts = @_;
  473   } else {
  474     %opts = ();
  475     $inList = [$inList, @_];
  476   }
  477 
  478   set_default_options(\%opts,
  479                       '_filter_name' => 'mbox',
  480                       'valign' => 'middle',
  481                       'allowbreaks' => 'no',
  482                       'allow_unknown_options'=> 0);
  483   if(! $opts{'allowbreaks'}) { $opts{'allowbreaks'}='no';}
  484   my $out = "";
  485   my $j;
  486   my ($brh, $erh) = ("",""); # Start and end raw html if needed
  487   if($main::displayMode eq 'Latex2HTML') {
  488     $brh = "\\begin{rawhtml}";
  489     $erh = "\\end{rawhtml}";
  490   }
  491   my @hlist = @{$inList};
  492   if($main::displayMode eq 'TeX') {
  493     if($opts{allowbreaks} ne 'no') {$out .= '\mbox{';}
  494     for $j (@hlist) { $out .= $j;}
  495     if($opts{allowbreaks} ne 'no') {$out .= '}';}
  496   } else {
  497     $out .= qq!$brh<table><tr valign="$opts{'valign'}">$erh!;
  498     for $j (@hlist) {
  499       $out .= qq!$brh<td align="center" nowrap="nowrap">$erh$j$brh</td>$erh!;
  500     }
  501     $out .= "$brh</table>$erh";
  502   }
  503   return $out;
  504 }
  505 
  506 
  507 =head4   ra_flatten_matrix
  508 
  509     Usage:   ra_flatten_matrix($A)
  510 
  511       where $A is a matrix object
  512       The output is a reference to an array.  The matrix is placed in the array by iterating
  513       over  columns on the inside
  514       loop, then over the rows. (e.g right to left and then down, as one reads text)
  515 
  516 
  517 =cut
  518 
  519 
  520 sub ra_flatten_matrix{
  521   my $matrix = shift;
  522   warn "The argument must be a matrix object" unless ref($matrix) =~ /Matrix/;
  523   my @array = ();
  524   my ($rows, $cols ) = $matrix->dim();
  525   foreach my $i (1..$rows) {
  526     foreach my $j (1..$cols) {
  527         push(@array, $matrix->element($i,$j)  );
  528       }
  529     }
  530     \@array;
  531 }
  532 
  533 # This subroutine is probably obsolete and not generally useful.  It was patterned after the APL
  534 # constructs for multiplying matrices. It might come in handy for non-standard multiplication of
  535 # of matrices (e.g. mod 2) for indice matrices.
  536 sub apl_matrix_mult{
  537   my $ra_a= shift;
  538   my $ra_b= shift;
  539   my %options = @_;
  540   my $rf_op_times= sub {$_[0] *$_[1]};
  541   my $rf_op_plus = sub {my $sum = 0; my @in = @_; while(@in){ $sum = $sum + shift(@in) } $sum; };
  542   $rf_op_times = $options{'times'} if defined($options{'times'}) and ref($options{'times'}) eq 'CODE';
  543   $rf_op_plus = $options{'plus'} if defined($options{'plus'}) and ref($options{'plus'}) eq 'CODE';
  544   my $rows = @$ra_a;
  545   my $cols = @{$ra_b->[0]};
  546   my $k_size = @$ra_b;
  547   my $out ;
  548   my ($i, $j, $k);
  549   for($i=0;$i<$rows;$i++) {
  550     for($j=0;$j<$cols;$j++) {
  551         my @r = ();
  552         for($k=0;$k<$k_size;$k++) {
  553           $r[$k] =  &$rf_op_times($ra_a->[$i]->[$k] , $ra_b->[$k]->[$j]);
  554         }
  555       $out->[$i]->[$j] = &$rf_op_plus( @r );
  556     }
  557   }
  558   $out;
  559 }
  560 
  561 sub matrix_mult {
  562   apl_matrix_mult($_[0], $_[1]);
  563 }
  564 
  565 sub make_matrix{
  566   my $function = shift;
  567   my $rows = shift;
  568   my $cols = shift;
  569   my ($i, $j, $k);
  570   my $ra_out;
  571   for($i=0;$i<$rows;$i++) {
  572     for($j=0;$j<$cols;$j++) {
  573       $ra_out->[$i]->[$j] = &$function($i,$j);
  574     }
  575   }
  576   $ra_out;
  577 }
  578 
  579 # sub format_answer{
  580 #   my $ra_eigenvalues = shift;
  581 #   my $ra_eigenvectors = shift;
  582 #   my $functionName = shift;
  583 #   my @eigenvalues=@$ra_eigenvalues;
  584 #   my $size= @eigenvalues;
  585 #   my $ra_eigen = make_matrix( sub {my ($i,$j) = @_; ($i==$j) ? "e^{$eigenvalues[$j] t}": 0 }, $size,$size);
  586 #   my $out = qq!
  587 #         $functionName(t) =! .
  588 #                             displayMatrix(apl_matrix_mult($ra_eigenvectors,$ra_eigen,
  589 #                                     'times'=>sub{($_[0] and $_[1]) ? "$_[0]$_[1]"  : ''},
  590 #                                     'plus'=>sub{ my $out = join("",@_); ($out) ?$out : '0' }
  591 #                                     ) ) ;
  592 #        $out;
  593 # }
  594 # sub format_vector_answer{
  595 #   my $ra_eigenvalues = shift;
  596 #   my $ra_eigenvectors = shift;
  597 #   my $functionName = shift;
  598 #   my @eigenvalues=@$ra_eigenvalues;
  599 #   my $size= @eigenvalues;
  600 #   my $ra_eigen = make_matrix( sub {my ($i,$j) = @_; ($i==$j) ? "e^{$eigenvalues[$j] t}": 0 }, $size,$size);
  601 #   my $out = qq!
  602 #         $functionName(t) =! .
  603 #                             displayMatrix($ra_eigenvectors)."e^{$eigenvalues[0] t}" ;
  604 #        $out;
  605 # }
  606 # sub format_question{
  607 #   my $ra_matrix = shift;
  608 #   my $out = qq! y'(t) = ! . displayMatrix($B). q! y(t)!
  609 #
  610 # }
  611 
  612 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9