# Solver Using Cramer's Rule to Solve Systems with 3 variables

Algebra ->  Algebra  -> Matrices-and-determiminant -> Solver Using Cramer's Rule to Solve Systems with 3 variables      Log On

 Ad: Algebrator™ solves your algebra problems and provides step-by-step explanations! Ad: Algebra Solved!™: algebra software solves algebra homework problems with step-by-step help!

 Algebra: Matrices, determinant, Cramer rule Solvers Lessons Answers archive Quiz In Depth

### Source code of 'Using Cramer's Rule to Solve Systems with 3 variables'

This Solver (Using Cramer's Rule to Solve Systems with 3 variables) was created by by jim_thompson5910(28476)  : View Source, Show, Put on YOUR site
About jim_thompson5910: I charge $2 a problem (for steps shown) or$1 a problem for answers only. Email: jim_thompson5910@hotmail.com Website: http://www.freewebs.com/jimthompson5910/home.html

 ==section input This solver will show you how to solve a system of equations with 3 variables in 3 equations (provided a solution exists) using Cramer's Rule. Enter the numerical entries of the system of equations (enter numbers only):
*[input my_a=10]x + *[input my_b=2]y + *[input my_c=3]z = *[input b_1=20]
*[input my_d=4]x + *[input my_e=5]y + *[input my_f=6]z = *[input b_2=47]
*[input my_g=7]x + *[input my_h=8]y + *[input my_i=9]z = *[input b_3=74]
Let me know if you encounter any errors. ==section solution perl ## --------------------------- Subroutines ------------------------------------------ sub rationalize_denominator { die "Needs two arguments " if @_!=2; my ($exp,$print)=@_; my ($num,$denom)=split(/\//,$exp); if($denom!~m/sqrt/) {warn "Denominator doesn't have square root "; return $exp;} my @root_denom=$denom=~m/(sqrt$$.*?$$)/g; my ($temp_num,$temp_denom); $temp_num=$temp_denom=join("",@root_denom); #for(my $i=0;$i<@root_denom;$i++) #{} my$new_denom=join("",@root_denom); $new_denom=~s/sqrt$$(.*?)$$/$1/g; my $ans=clean_up("($num$temp_num)/($new_denom)"); ## Last few lines allow for overloading return values #-- undefined context -- return nothing return if ( ! defined wantarray ); #-- list/array context -- return array return "$num$temp_num",$new_denom if ( wantarray ); #-- neither undefined nor list context, return scalar return$ans; } sub clean { my $exp=$_[0]; $exp=~s/\+\-/\-/g;$exp=~s/\-\-/\+/g; $exp=~s/(\D)$$(\-?\d+)$$(\D)/$1$2$3/g; return $exp; } sub generate_fraction { my$exp=$_[0]; my @array=split(/\//,$exp); $array[1]=1 if @array==1; return @array; } sub convert_to_latex { my$exp=$_[0]; my @fraction=generate_fraction($exp); my $ans="\\frac{$fraction[0]}{$fraction[1]}" if$fraction[1]!=1; $ans="$exp" if $fraction[1]==1;$ans=~s/^(\\frac\{)\-/\-$1/; return$ans; } # given a number n, subroutine will generate all perfect squares up to n # eg n=103 ----> perfect squares: 1,4,9,16,25,36,49,64,81,100 sub generate_perfect_squares { my $n=$_[0]; my $sqrt_n=int(sqrt($n)); my @ans; for(my $i=0;$i<=$sqrt_n;$i++) {push(@ans,$i**2);} shift(@ans) if$ans[0]==0; return @ans; } # simplify sqrt(72)=sqrt(36)*sqrt(2)=6*sqrt(2) sub simplify_square_root { my $number=$_[0]; my $negative_flag=0; if($number=~m/^\-/) {$negative_flag=1;$number=~s/\-//;} my $sq=sqrt($number); if($sq!~m/\./) {return$sq if $negative_flag==0; return "$sq*i" if $negative_flag==1;} my @factors=factor_generate($number); if($negative_flag==0) { if($factors[0] eq 'prime') {return ("1","sqrt($number)") if ( wantarray ); return "sqrt($number)";} } else { if($factors[0] eq 'prime') {return ("i","sqrt($number)") if ( wantarray ); return "i*sqrt($number)";} } my @perfect_squares=generate_perfect_squares($number); my @factor; for(my $i=0;$i<@perfect_squares;$i++) { my$temp=$number/$perfect_squares[$i]; push(@factor,$perfect_squares[$i]) if$temp!~m/\./; } if(@factor==0) { if($negative_flag==0) {return ("1","sqrt($number)") if ( wantarray ); return "sqrt($number)";} else {return ("i","sqrt($number)") if ( wantarray ); return "i*sqrt($number)";} } my$factor1=$number/$factor[-1]; my $factor2=$number/$factor1; my$sq_factor1=sqrt($factor1); my$sq_factor2=sqrt($factor2); if($sq_factor1!~m/\./) {$factor1=$sq_factor1;} else {$factor1="sqrt($factor1)";} if($sq_factor2!~m/\./) {$factor2=$sq_factor2;} else {$factor2="sqrt($factor2)";} if(($sq_factor1!~m/\./)&&($sq_factor2!~m/\./)) {my$temp=$factor2*$factor1; return $temp if$negative_flag==0; return "$temp*i" if$negative_flag==1; } if($negative_flag==1) {$factor2.="i";} #print " factor2,factor1: $factor2,$factor1 \n\n"; ## Last few lines allow for overloading return values #-- undefined context -- return nothing return if ( ! defined wantarray ); #-- list/array context -- return array return ($factor2,$factor1) if ( wantarray ); #-- neither undefined nor list context, return scalar if($negative_flag==0) {return "$factor2*$factor1";} else {return "$factor2*$factor1";} } sub factor_generate { my$number=$_[0]; my ($count,@factors); $count=0; for(my$i=2;$i1; ## if input arg is an array if(($a[0]=~m/\./) or ($a[1]=~m/\./)) { return$a[0]/$a[1]; } if(@a>2) {die "ERROR: More than 2 input arguments";} foreach (@a) {die "Cannot handle decimal numbers " if$_=~m/\./;} if($a[1]==0) {die "ERROR: Division by zero";} if($a[0]==0) {return $a[0];} my$gcf=gcf($a[0],$a[1]); $a[0]/=$gcf; $a[1]/=$gcf; my $answer_string=join("/",@a);$answer_string=~s/\/1$//; # remove denominator of 1 ## Last few lines allow for overloading return values #-- undefined context -- return nothing return if ( ! defined wantarray ); #-- list/array context -- return array return @a if ( wantarray ); #-- neither undefined nor list context, return scalar return$answer_string; } # invert a/b to get b/a sub invert_fraction {die "More than 2 arguments " if @_>2; my @fraction=generate_fraction($_[0]) if @_==1; @fraction=@_ if @_==2; die "Numerator is zero -- cannot invert " if$fraction[0]==0; die "Error Division by zero " if $fraction[1]==0; ## optional? if($fraction[0]=~m/\-/) {$fraction[0]=abs($fraction[0]); $fraction[1]="-$fraction[1]";} ## Last few lines allow for overloading return values #-- undefined context -- return nothing return if ( ! defined wantarray ); #-- list/array context -- return array return reverse(@fraction) if ( wantarray ); #-- neither undefined nor list context, return scalar return join("/",reverse(@fraction)); } # input a fraction like a/b and find rationalized equivalent of sqrt(a/b) # eg sqrt(1/2)=sqrt(2)/2 or sqrt(8/7)=(2*sqrt(14))/7 sub sqrt_of_fraction { my ($exp,$print)=@_ if @_==2; $exp=$_[0] if @_==1; $print=0 unless$print; $exp=reduce($exp); my @fraction=generate_fraction($exp); if($fraction[1]==1) {my $temp=simplify_square_root($exp); return $temp;} my$sq_exp="sqrt($fraction[0])/sqrt($fraction[1])"; my $rationalized_denominator_exp=rationalize_denominator($sq_exp,0); my @radicands=$rationalized_denominator_exp=~m/sqrt$$(.*?)$$/g; my$product=$radicands[0]*$radicands[1]; my $new_num=simplify_square_root($product); if($new_num!~m/sqrt/) {my$temp=reduce($new_num,$fraction[1]); return $temp;} my ($outer_coefficient,$new_radicand)=$new_num=~m/^(\d+)?\*?sqrt$$(.*?)$$/; $outer_coefficient=1 if$new_num=~m/^sqrt$$(.*?)$$/; $outer_coefficient=-1 if$new_num=~m/^\-sqrt$$(.*?)$$/; #$new_radicand=$1 if $new_num=~m/^sqrt$$(.*?)$$/; my ($reduced_num,$reduced_denom)=reduce($outer_coefficient,$fraction[1]); my$ans="($reduced_num*sqrt($new_radicand))/$reduced_denom";$ans=~s/$$1\*(.*?)$$\//$1\//; return$ans; } #my $exp="8/7"; #my$ans=sqrt_of_fraction($exp,1); #print "ANS: {{{sqrt($exp)=$ans}}}\n"; ## main subroutine - Enter strings for operands and operator . ## Ex: rational_arithmetic(2,"2/3","+") ## or rational_arithmetic($num1,"@array","/") sub rat { my $arg_count=@_; if($arg_count!=3) {die "ERROR: You need to enter 3 arguments"; return;} my $operator=pop; # pull last element off of input array @_ if(($_[0]=~m/\./) or ($_[1]=~m/\./)) { my$ans=evaluate_decimal($_[0],$_[1],$operator); return$ans; } my @ans; for(my $i=0;$i<@_;$i++) {my$temp=$_[$i]; $temp=~s/\///;$temp=~s/\-//g; $temp=~s/\s//g; if($temp=~m/(\D)/) {print "TEMP: $temp\n"; die "ERROR: nonnumerical character \"$1\" ";} } my @a=generate_fraction($_[0]); my @b=generate_fraction($_[1]); if(($a[1]==0)||($b[1]==0)) {print "..$a[0]..$a[1]..$b[0]..$b[1]..\n"; die "ERROR: Division by zero";} if($operator eq '+') {my$lcm=lcm($a[1],$b[1]); $a[0]=($lcm/$a[1])*$a[0]; $b[0]=($lcm/$b[1])*$b[0]; $a[1]=$b[1]=$lcm; @ans=($a[0]+$b[0],$a[1]); } elsif($operator eq '-') {my$lcm=lcm($a[1],$b[1]); $a[0]=($lcm/$a[1])*$a[0]; $b[0]=($lcm/$b[1])*$b[0]; $a[1]=$b[1]=$lcm; @ans=($a[0]-$b[0],$a[1]); } elsif($operator eq '*') {@ans=($a[0]*$b[0],$a[1]*$b[1]);} elsif($operator eq '/') {@ans=($a[0]*$b[1],$a[1]*$b[0]);} elsif($operator eq '^') {if($b[1]==1) {@ans=($a[0]**$b[0],$a[1]**$b[0]);} elsif(($b[0]==1)&&($b[1]==2)) {my $temp=sqrt_of_fraction(join("/",@a)); return$temp} else {die "ERROR: exponent ".join("/",@b)." is a fraction b_1=$b[1]"; return;} } else {die "ERROR: \"$operator\" is not a valid operator";} ## Last few lines allow for overloading return values #-- undefined context -- return nothing return if ( ! defined wantarray ); #-- list/array context -- return array return @ans if ( wantarray ); #-- neither undefined nor list context, return scalar return join("/",@ans); } #format: input expression and list of characters that are deemed safe. If it finds any nonword character, it will return 1 for error # input: 2 strings # output: sub check_for_illegal_characters { die "Needs 3 arguments " if @_!=3; my ($exp,$safe_chars,$flag)=@_; ##note: flag =1 words allowed flag=0 only numeric characters allowed$exp=~s/\s//g; my @safe_chars=split(/,/,$safe_chars); @safe_chars=map(quotemeta($_),@safe_chars); my (@illegal_chars,$illegal_chars_string); for(my$i=0;$i<@safe_chars;$i++) {$exp=~s/$safe_chars[$i]//g;} my$regexp="\\W+" if $flag==1; # pick out any non-word chars$regexp="\\D+" if $flag==0; # pick out any non-numeric chars @illegal_chars=$exp=~m/($regexp)/g;$illegal_chars_string=join(" ",@illegal_chars); if($exp=~m/$regexp/) { return (1,$illegal_chars_string) if ( wantarray ); return 1; } ## found non-word char, so must return error if($exp!~m/$regexp/) { return (0,"null") if ( wantarray ); return 0; } ## did not find non-word char } ## if one operand has a decimal portion, use this subroutine sub evaluate_decimal { die "ERROR: You need to enter 3 arguments" if @_!=3; my @a=generate_fraction($_[0]); my @b=generate_fraction($_[1]); my$operator=$_[2]; my ($num,$denom); if($operator eq '+') { $num=$a[0]*$b[1]+$b[0]*$a[1];$denom=$a[1]*$b[1]; } elsif($operator eq '-') {$num=$a[0]*$b[1]-$b[0]*$a[1]; $denom=$a[1]*$b[1]; } elsif($operator eq '*') { $num=$a[0]*$b[0];$denom=$a[1]*$b[1]; } elsif($operator eq '/') {$num=$a[0]*$b[1]; $denom=$a[1]*$b[0]; } elsif($operator eq '^') { my $exponent=$b[0]/$b[1];$num=$a[0]**$exponent; $denom=$a[1]**$exponent; } else { die "ERROR: \"$operator\" is not a valid operator"; } my $ans=$num/$denom; return$ans; } sub determinant_3x3 { die "Needs 9 entries!" if @_!=9; my ($my_a,$my_b,$my_c,$my_d,$my_e,$my_f,$my_g,$my_h,$my_i)=@_; ## calculate first determinant my$det1_prod1=reduce(rat($my_e,$my_i,"*")); $det1_prod1=~s/\/1$//; ## remove denominator of 1 my $det1_prod2=reduce(rat($my_f,$my_h,"*"));$det1_prod2=~s/\/1$//; ## remove denominator of 1 my$det1_diff=reduce(rat($det1_prod1,$det1_prod2,"-")); $det1_diff=~s/\/1$//; ## remove denominator of 1 my $det1_prod3=reduce(rat($my_a,$det1_diff,"*"));$det1_prod3=~s/\/1$//; ## remove denominator of 1 ##------------------------ ## calculate second determinant my$det2_prod1=reduce(rat($my_d,$my_i,"*")); $det2_prod1=~s/\/1$//; ## remove denominator of 1 my $det2_prod2=reduce(rat($my_f,$my_g,"*"));$det2_prod2=~s/\/1$//; ## remove denominator of 1 my$det2_diff=reduce(rat($det2_prod1,$det2_prod2,"-")); $det2_diff=~s/\/1$//; ## remove denominator of 1 my $det2_prod3=reduce(rat($my_b,$det2_diff,"*"));$det2_prod3=~s/\/1$//; ## remove denominator of 1 ##------------------------ ## calculate third determinant my$det3_prod1=reduce(rat($my_d,$my_h,"*")); $det3_prod1=~s/\/1$//; ## remove denominator of 1 my $det3_prod2=reduce(rat($my_e,$my_g,"*"));$det3_prod2=~s/\/1$//; ## remove denominator of 1 my$det3_diff=reduce(rat($det3_prod1,$det3_prod2,"-")); $det3_diff=~s/\/1$//; ## remove denominator of 1 my $det3_prod3=reduce(rat($my_c,$det3_diff,"*"));$det3_prod3=~s/\/1$//; ## remove denominator of 1 my$ans=reduce(rat($det1_prod3,$det2_prod3,"-")); $ans=reduce(rat($ans,$det3_prod3,"+")); return$ans; } ## ------------------------------ End Subroutines -------------------------------------------- ## ------------------------------ Error Checking --------------------------------------------- foreach($my_a,$my_b,$my_c,$my_d,$my_e,$my_f,$my_g,$my_h,$my_i) { if($_=~m/[a-z]/) { print "ERROR: Please enter numerical values only (no variables)"; goto end; } } ## ------------------------------ End Error Checking -------------------------------------------- print " {{{system($my_a*x+$my_b*y+$my_c*z=$b_1,$my_d*x+$my_e*y+$my_f*z=$b_2,$my_g*x+$my_h*y+$my_i*z=$b_3)}}} "; print " First let {{{A=(matrix(3,3,$my_a,$my_b,$my_c,$my_d,$my_e,$my_f,$my_g,$my_h,$my_i))}}}. This is the matrix formed by the coefficients of the given system of equations. Take note that the right hand values of the system are {{{$b_1}}}, {{{$b_2}}}, and {{{$b_3}}} and they are highlighted here: {{{system($my_a*x+$my_b*y+$my_c*z=highlight($b_1),$my_d*x+$my_e*y+$my_f*z=highlight($b_2),$my_g*x+$my_h*y+$my_i*z=highlight($b_3))}}} These values are important as they will be used to replace the columns of the matrix A. "; my $det_A=determinant_3x3($my_a,$my_b,$my_c,$my_d,$my_e,$my_f,$my_g,$my_h,$my_i); print " Now let's calculate the the determinant of the matrix A to get {{{abs(A)=$det_A}}}. To save space, I'm not showing the calculations for the determinant. However, if you need help with calculating the determinant of the matrix A, check out this solver. Notation note: {{{abs(A)}}} denotes the determinant of the matrix A. "; if($det_A eq '0') { print " Since the determinant of matrix A is zero, this means that we cannot use Cramer's Rule. Why? Remember that each solution 'x', 'y', and 'z' are found by dividing by the determinant of A. If that determinant is zero, then you'll be dividing by zero, which is undefined. So that means you have to use an alternate method to find the solution. "; goto end; } print " --------------------------------------------------------- "; my $det_Ax=determinant_3x3($b_1,$my_b,$my_c,$b_2,$my_e,$my_f,$b_3,$my_h,$my_i); my $ans_x=reduce(rat($det_Ax,$det_A,"/")); print " Now replace the first column of A (that corresponds to the variable 'x') with the values that form the right hand side of the system of equations. We will denote this new matrix {{{A[x]}}} (since we're replacing the 'x' column so to speak). {{{A[x]=(matrix(3,3,highlight($b_1),$my_b,$my_c,highlight($b_2),$my_e,$my_f,highlight($b_3),$my_h,$my_i))}}} Now compute the determinant of {{{A[x]}}} to get {{{abs(A[x])=$det_Ax}}}. Again, as a space saver, I didn't include the calculations of the determinant. Check out this solver to see how to find this determinant. To find the first solution, simply divide the determinant of {{{A[x]}}} by the determinant of {{{A}}} to get: {{{x=(abs(A[x]))/(abs(A))=($det_Ax)/($det_A)=$ans_x}}} So the first solution is {{{x=$ans_x}}} "; print " --------------------------------------------------------- We'll follow the same basic idea to find the other two solutions. Let's reset by letting {{{A=(matrix(3,3,$my_a,$my_b,$my_c,$my_d,$my_e,$my_f,$my_g,$my_h,$my_i))}}} again (this is the coefficient matrix). "; my $det_Ay=determinant_3x3($my_a,$b_1,$my_c,$my_d,$b_2,$my_f,$my_g,$b_3,$my_i); my $ans_y=reduce(rat($det_Ay,$det_A,"/")); print " Now replace the second column of A (that corresponds to the variable 'y') with the values that form the right hand side of the system of equations. We will denote this new matrix {{{A[y]}}} (since we're replacing the 'y' column in a way). {{{A[x]=(matrix(3,3,$my_a,highlight($b_1),$my_c,$my_d,highlight($b_2),$my_f,$my_g,highlight($b_3),$my_i))}}} Now compute the determinant of {{{A[y]}}} to get {{{abs(A[y])=$det_Ay}}}. To find the second solution, divide the determinant of {{{A[y]}}} by the determinant of {{{A}}} to get: {{{y=(abs(A[y]))/(abs(A))=($det_Ay)/($det_A)=$ans_y}}} So the second solution is {{{y=$ans_y}}} "; print " --------------------------------------------------------- "; my$det_Az=determinant_3x3($my_a,$my_b,$b_1,$my_d,$my_e,$b_2,$my_g,$my_h,$b_3); my$ans_z=reduce(rat($det_Az,$det_A,"/")); print " Let's reset again by letting {{{A=(matrix(3,3,$my_a,$my_b,$my_c,$my_d,$my_e,$my_f,$my_g,$my_h,$my_i))}}} which is the coefficient matrix. Replace the third column of A (that corresponds to the variable 'z') with the values that form the right hand side of the system of equations. We will denote this new matrix {{{A[z]}}} {{{A[z]=(matrix(3,3,$my_a,$my_b,highlight($b_1),$my_d,$my_e,highlight($b_2),$my_g,$my_h,highlight($b_3)))}}} Now compute the determinant of {{{A[z]}}} to get {{{abs(A[z])=$det_Az}}}. To find the third solution, divide the determinant of {{{A[z]}}} by the determinant of {{{A}}} to get: {{{z=(abs(A[z]))/(abs(A))=($det_Az)/($det_A)=$ans_z}}} So the third solution is {{{z=$ans_z}}} "; print " ==================================================================================== Final Answer: "; print " So the three solutions are {{{x=$ans_x}}}, {{{y=$ans_y}}}, and {{{z=$ans_z}}} giving the ordered triple ($ans_x,$ans_y, \$ans_z) Note: there is a lot of work that is hidden in finding the determinants. Take a look at this 3x3 Determinant Solver to see how to get each determinant. "; end: ==section output ==section check