| … | |
… | |
| 165 | |
165 | |
| 166 | #construct the answer evaluator |
166 | #construct the answer evaluator |
| 167 | my $answer_evaluator = new AnswerEvaluator; |
167 | my $answer_evaluator = new AnswerEvaluator; |
| 168 | |
168 | |
| 169 | $answer_evaluator->{debug} = $mat_params{debug}; |
169 | $answer_evaluator->{debug} = $mat_params{debug}; |
| 170 | $answer_evaluator->ans_hash( correct_ans => pretty_print($mat_params{correct_ans}), |
170 | $answer_evaluator->ans_hash( correct_ans => display_correct_vecs($mat_params{correct_ans}), |
| 171 | rm_correct_ans => $matrix, |
171 | rm_correct_ans => $matrix, |
| 172 | zeroLevelTol => $mat_params{zeroLevelTol}, |
172 | zeroLevelTol => $mat_params{zeroLevelTol}, |
| 173 | debug => $mat_params{debug}, |
173 | debug => $mat_params{debug}, |
| 174 | mode => $mat_params{mode}, |
174 | mode => $mat_params{mode}, |
| 175 | help => $mat_params{help}, |
175 | help => $mat_params{help}, |
| … | |
… | |
| 471 | $rh_ans->{ans_label} =~ /ArRaY(\d+)\[\d+,\d+,\d+\]/; |
471 | $rh_ans->{ans_label} =~ /ArRaY(\d+)\[\d+,\d+,\d+\]/; |
| 472 | my $ans_num = $1; |
472 | my $ans_num = $1; |
| 473 | my @keys = grep /ArRaY$ans_num/, keys(%{$main::inputs_ref}); |
473 | my @keys = grep /ArRaY$ans_num/, keys(%{$main::inputs_ref}); |
| 474 | my $key; |
474 | my $key; |
| 475 | my @array = (); |
475 | my @array = (); |
| 476 | #my @latex = (); |
|
|
| 477 | my ($i,$j,$k) = (0,0,0); |
476 | my ($i,$j,$k) = (0,0,0); |
| 478 | |
477 | |
| 479 | #the keys aren't in order, so their info has to be put into the array before doing anything with it |
478 | #the keys aren't in order, so their info has to be put into the array before doing anything with it |
| 480 | foreach $key (@keys){ |
479 | foreach $key (@keys){ |
| 481 | $key =~ /ArRaY\d+\[(\d+),(\d+),(\d+)\]/; |
480 | $key =~ /ArRaY\d+\[(\d+),(\d+),(\d+)\]/; |
| 482 | ($i,$j,$k) = ($1,$2,$3); |
481 | ($i,$j,$k) = ($1,$2,$3); |
| 483 | $array[$i][$j][$k] = ${$main::inputs_ref}{'ArRaY'.$ans_num.'['.$i.','.$j.','.$k.']'}; |
482 | $array[$i][$j][$k] = ${$main::inputs_ref}{'ArRaY'.$ans_num.'['.$i.','.$j.','.$k.']'}; |
| 484 | } |
483 | } |
| 485 | |
484 | |
| 486 | my $display_ans = ""; |
485 | my $display_ans = ""; |
| 487 | |
486 | |
| 488 | for( $i=0; $i < scalar(@array) ; $i ++ ) |
487 | for( $i=0; $i < scalar(@array) ; $i ++ ) |
| 489 | { |
488 | { |
| 490 | $display_ans .= " ["; |
489 | $display_ans .= " ["; |
| 491 | $rh_ans->{preview_text_string} .= ' ['; |
490 | $rh_ans->{preview_text_string} .= ' ['; |
| 492 | $rh_ans->{preview_latex_string} .= ' ['; |
491 | $rh_ans->{preview_latex_string} .= '\begin{pmatrix} '; |
| 493 | for( $j = 0; $j < scalar( @{$array[$i]} ) ; $j++ ) |
492 | for( $j = 0; $j < scalar( @{$array[$i]} ) ; $j++ ) |
| 494 | { |
493 | { |
| 495 | $display_ans .= " ["; |
494 | $display_ans .= " ["; |
| 496 | $rh_ans->{preview_text_string} .= ' ['; |
495 | $rh_ans->{preview_text_string} .= ' ['; |
| 497 | $rh_ans->{preview_latex_string} .= ' ['; |
|
|
| 498 | for( $k = 0; $k < scalar( @{$array[$i][$j]} ) ; $k ++ ){ |
496 | for( $k = 0; $k < scalar( @{$array[$i][$j]} ) ; $k ++ ){ |
| 499 | my $entry = $array[$i][$j][$k]; |
497 | my $entry = $array[$i][$j][$k]; |
| 500 | $entry = math_constants($entry); |
498 | $entry = math_constants($entry); |
| 501 | # This parser code was origianally taken from PGanswermacros::check_syntax |
499 | # This parser code was origianally taken from PGanswermacros::check_syntax |
| 502 | # but parts of it needed to be slighty modified for this context |
500 | # but parts of it needed to be slighty modified for this context |
| 503 | my $parser = new AlgParserWithImplicitExpand; |
501 | my $parser = new AlgParserWithImplicitExpand; |
| … | |
… | |
| 506 | if ( ref($ret) ) { ## parsed successfully |
504 | if ( ref($ret) ) { ## parsed successfully |
| 507 | $parser -> tostring(); |
505 | $parser -> tostring(); |
| 508 | $parser -> normalize(); |
506 | $parser -> normalize(); |
| 509 | $entry = $parser -> tostring(); |
507 | $entry = $parser -> tostring(); |
| 510 | $rh_ans->{preview_text_string} .= $entry.","; |
508 | $rh_ans->{preview_text_string} .= $entry.","; |
| 511 | $rh_ans->{preview_latex_string} .= $parser -> tolatex().","; |
509 | $rh_ans->{preview_latex_string} .= $parser -> tolatex() . '& '; |
| 512 | #$latex[$i][$j][$k] = "\\{".$parser -> tolatex()."\\}"; |
|
|
| 513 | |
510 | |
| 514 | } else { ## error in parsing |
511 | } else { ## error in parsing |
| 515 | $rh_ans->{'student_ans'} = 'syntax error:'.$display_ans. $parser->{htmlerror}, |
512 | $rh_ans->{'student_ans'} = 'syntax error:'.$display_ans. $parser->{htmlerror}, |
| 516 | $rh_ans->{'ans_message'} = $display_ans.$parser -> {error_msg}, |
513 | $rh_ans->{'ans_message'} = $display_ans.$parser -> {error_msg}, |
| 517 | $rh_ans->{'preview_text_string'} = '', |
514 | $rh_ans->{'preview_text_string'} = '', |
| 518 | $rh_ans->{'preview_latex_string'} = '', |
|
|
| 519 | $rh_ans->throw_error('SYNTAX', 'syntax error in answer:'.$display_ans.$parser->{htmlerror} . "$main::BR" .$parser -> {error_msg}.".$main::BR"); |
515 | $rh_ans->throw_error('SYNTAX', 'syntax error in answer:'.$display_ans.$parser->{htmlerror} . "$main::BR" .$parser -> {error_msg}.".$main::BR"); |
| 520 | } |
516 | } |
| 521 | |
517 | |
| 522 | my ($inVal,$PG_eval_errors,$PG_full_error_report) = PG_answer_eval($entry); |
518 | my ($inVal,$PG_eval_errors,$PG_full_error_report) = PG_answer_eval($entry); |
| 523 | if ($PG_eval_errors) { |
519 | if ($PG_eval_errors) { |
| … | |
… | |
| 529 | $display_ans .= $entry.","; |
525 | $display_ans .= $entry.","; |
| 530 | $array[$i][$j][$k] = $entry; |
526 | $array[$i][$j][$k] = $entry; |
| 531 | } |
527 | } |
| 532 | } |
528 | } |
| 533 | chop($rh_ans->{preview_text_string}); |
529 | chop($rh_ans->{preview_text_string}); |
| 534 | chop($rh_ans->{preview_latex_string}); |
|
|
| 535 | chop($display_ans); |
530 | chop($display_ans); |
| 536 | $rh_ans->{preview_text_string} .= '] ,'; |
531 | $rh_ans->{preview_text_string} .= '] ,'; |
| 537 | $rh_ans->{preview_latex_string} .= '] ,'; |
532 | $rh_ans->{preview_latex_string} .= '\\\\'; |
| 538 | $display_ans .= '] ,'; |
533 | $display_ans .= '] ,'; |
| 539 | |
534 | |
| 540 | } |
535 | } |
| 541 | chop($rh_ans->{preview_text_string}); |
536 | chop($rh_ans->{preview_text_string}); |
| 542 | chop($rh_ans->{preview_latex_string}); |
|
|
| 543 | chop($display_ans); |
537 | chop($display_ans); |
| 544 | $rh_ans->{preview_text_string} .= '] ,'; |
538 | $rh_ans->{preview_text_string} .= '] ,'; |
| 545 | $rh_ans->{preview_latex_string} .= '] ,'; |
539 | $rh_ans->{preview_latex_string} .= '\end{pmatrix}'.' , '; |
| 546 | $display_ans .= '] ,'; |
540 | $display_ans .= '] ,'; |
| 547 | } |
541 | } |
| 548 | chop($rh_ans->{preview_text_string}); |
542 | chop($rh_ans->{preview_text_string}); |
| 549 | chop($rh_ans->{preview_latex_string}); |
543 | chop($rh_ans->{preview_latex_string}); |
|
|
544 | chop($rh_ans->{preview_latex_string}); |
|
|
545 | chop($rh_ans->{preview_latex_string}); |
| 550 | chop($display_ans); |
546 | chop($display_ans); |
| 551 | |
547 | |
| 552 | #for( $i = 0 ; $i < scalar( @latex ); $i++ ){ |
|
|
| 553 | # $latex[$i] = display_matrix($latex[$i]); |
|
|
| 554 | #} |
|
|
| 555 | #$rh_ans->{preview_latex_string} = mbox(\@latex); |
|
|
| 556 | my @temp = (); |
548 | my @temp = (); |
| 557 | for( $i = 0 ; $i < scalar( @array ); $i++ ){ |
549 | for( $i = 0 ; $i < scalar( @array ); $i++ ){ |
| 558 | push @temp , display_matrix($array[$i], 'left'=>'.', 'right'=>'.'); |
550 | push @temp , display_matrix($array[$i], 'left'=>'.', 'right'=>'.'); |
| 559 | push @temp , "," unless $i == scalar(@array) - 1; |
551 | push @temp , "," unless $i == scalar(@array) - 1; |
| 560 | } |
552 | } |
| … | |
… | |
| 582 | |
574 | |
| 583 | for( ; $i < $num ; $i ++ ) |
575 | for( ; $i < $num ; $i ++ ) |
| 584 | { |
576 | { |
| 585 | for( $j = $i+1; $j < $num ; $j++ ) |
577 | for( $j = $i+1; $j < $num ; $j++ ) |
| 586 | { |
578 | { |
| 587 | my $sum = 0; |
579 | if( $vecs[$i]->scalar_product($vecs[$j]) > $main::functZeroLevelTolDefault ) |
| 588 | my $k = 0; |
|
|
| 589 | |
|
|
| 590 | for( ; $k < $length; $k++ ) { |
|
|
| 591 | $sum += $vecs[$i]->[0][$k][0]*$vecs[$j]->[0][$k][0]; |
|
|
| 592 | } |
|
|
| 593 | |
|
|
| 594 | if( $sum > $main::functZeroLevelTolDefault ) |
|
|
| 595 | { |
580 | { |
| 596 | if( ref( $vec_ref ) eq 'AnswerHash' ){ |
581 | if( ref( $vec_ref ) eq 'AnswerHash' ){ |
| 597 | $vec_ref->{score} = 0; |
582 | $vec_ref->{score} = 0; |
| 598 | if( $vec_ref->{help} =~ /orthogonal|orthonormal|verbose/ ) |
583 | if( $vec_ref->{help} =~ /orthogonal|orthonormal|verbose/ ) |
| 599 | { |
584 | { |
| … | |
… | |
| 630 | my $num = scalar(@vecs); |
615 | my $num = scalar(@vecs); |
| 631 | my $length = $vecs[0]->[1]; |
616 | my $length = $vecs[0]->[1]; |
| 632 | |
617 | |
| 633 | for( ; $i < $num ; $i ++ ) |
618 | for( ; $i < $num ; $i ++ ) |
| 634 | { |
619 | { |
| 635 | my $sum = 0; |
|
|
| 636 | my $k = 0; |
|
|
| 637 | |
|
|
| 638 | for( ; $k < $length; $k++ ) { |
|
|
| 639 | $sum += $vecs[$i]->[0][$k][0]*$vecs[$i]->[0][$k][0]; |
|
|
| 640 | } |
|
|
| 641 | if( abs(sqrt($sum) - 1) > $main::functZeroLevelTolDefault ) |
620 | if( abs(sqrt($vecs[$i]->scalar_product($vecs[$i]))- 1) > $main::functZeroLevelTolDefault ) |
| 642 | { |
621 | { |
| 643 | if( ref( $vec_ref ) eq 'AnswerHash' ){ |
622 | if( ref( $vec_ref ) eq 'AnswerHash' ){ |
| 644 | $vec_ref->{score} = 0; |
623 | $vec_ref->{score} = 0; |
| 645 | if( $vec_ref->{help} =~ /unit|orthonormal|verbose/ ) |
624 | if( $vec_ref->{help} =~ /unit|orthonormal|verbose/ ) |
| 646 | { |
625 | { |
| … | |
… | |
| 663 | 1; |
642 | 1; |
| 664 | } |
643 | } |
| 665 | } |
644 | } |
| 666 | |
645 | |
| 667 | sub display_correct_vecs{ |
646 | sub display_correct_vecs{ |
| 668 | my ( $vec_ref,%opts ) = @_; |
647 | my ( $ra_vecs,%opts ) = @_; |
| 669 | my $corr_matrix; |
648 | my @ra_vecs = @{$ra_vecs}; |
| 670 | my @vecs = (); |
|
|
| 671 | |
|
|
| 672 | if( ref($vec_ref) eq 'AnswerHash' ) |
|
|
| 673 | { |
|
|
| 674 | $corr_matrix = Matrix->new_from_col_vecs($vec_ref->{correct_ans}); |
|
|
| 675 | }else{ |
|
|
| 676 | $corr_matrix = Matrix->new_from_col_vecs($vec_ref); |
|
|
| 677 | } |
|
|
| 678 | |
|
|
| 679 | my @temp = (); |
649 | my @temp = (); |
| 680 | |
650 | |
| 681 | for( my $i = 0 ; $i < $corr_matrix->[2] ; $i++ ){ |
651 | for( my $i = 0 ; $i < scalar(@ra_vecs) ; $i++ ){ |
| 682 | push @temp, display_matrix($corr_matrix->column($i)); |
652 | push @temp, display_matrix(Matrix->new_from_col_vecs([$ra_vecs[$i]]),'left'=>'.','right'=>'.'); |
| 683 | push @temp, ","; |
653 | push @temp, ","; |
| 684 | } |
654 | } |
| 685 | |
655 | |
| 686 | if( def(@temp) ) |
|
|
| 687 | { |
|
|
| 688 | pop @temp; |
656 | pop @temp; |
| 689 | }else{ |
|
|
| 690 | @temp = [[" "]]; |
|
|
| 691 | } |
|
|
| 692 | |
|
|
| 693 | |
|
|
| 694 | |
657 | |
| 695 | mbox(\@temp); |
658 | mbox(\@temp); |
| 696 | |
659 | |
| 697 | } |
660 | } |
| 698 | |
661 | |