WeBWorK Problems

Reducing square roots using if, ifelse nested within a do loop

Reducing square roots using if, ifelse nested within a do loop

by tim Payer -
Number of replies: 5
Hello,

I am writing solutions to a number of selected problems. We prompt our calculus students to use their mechanics rather than calculators to reduce expressions and we would like the solutions we create in webwork to show the same. Thus there is a frequent need to reduce square roots to their simplest forms.

I attempted to write a do loop to accomplish this within a given problem.
The loop handles an if condition but once I start including an elseif and else I run into problems.

The offending lines of code are #96-#104 (for the elseif and else conditions) and i have them commented out.
This loop is currently disconnected from the problem at hand. I just want to know why these error statements are occurring.

As I see 3 conditions that have to be provided for: 
1.) The root reduces to an integer
2.) The root does not reduce.
3.)  Some squared factor can be pulled from the root.

Can you see where i might have gone wrong? The Syntax matches my Perl guide. But webwork does not like having those extra conditions.

Thanks,   tim
## DESCRIPTION
## Calculus
## ENDDESCRIPTION

## Tagged by tda2d

## DBsubject(Calculus - multivariable)
## DBchapter(Differentiation of multivariable functions)
## DBsection(Partial derivatives)
## Institution(Dartmouth)
## Level(2)
## TitleText1('Basic Multivariable Calculus')
## AuthorText1('Marsden, Tromba, Weinstein')
## EditionText1('3')
## Section1('2.6')
## Problem1('')
## KEYWORDS('tangent' 'slope')
## Library/Dartmouth/setMTWCh2S6/problem_2

DOCUMENT();
loadMacros("PG.pl",
           "PGbasicmacros.pl",
           "PGchoicemacros.pl",
           "PGanswermacros.pl",
           "PGauxiliaryFunctions.pl",
           "PGgraphmacros.pl",
           "Dartmouthmacros.pl");
 

## Do NOT show partial correct answers
$showPartialCorrectAnswers = 1;

## Lots of set up goes here
$x1 = random(1,8,1);
$y1 = random(1,8,1);

$a = random(1,4,1);
$a_x = clean_scalar_string($a, "x");

$b = random(1,4,1);
$b_y = clean_scalar_string($b, "y");

$c = random(1,4,1);
$c_xy = clean_scalar_string($c, "xy");

$ga = gcd($a,2);
$gb = gcd($b,2);
$gc = gcd($c,2);
$na = $a/$ga;
$nb = $b/$gb;
$nc = $c/$gc;
$da = 2/$ga;
$db = 2/$gb;
$dc = 2/$gc;

if($da ==1){
$fa=$na;
}
else{
$fa="\frac{$na}{$da}";
 }

if($db ==1){
$fb=$nb;
}
else{
$fb="\frac{$nb}{$db}";
 }

if($dc ==1){
$fc=$nc;
}
else{
$fc="\frac{$nc}{$dc}";
 }


$rad3 = $a*$x1+$b*$y1;
$rad4 = $c*$x1*$y1;
$rad1 = 2*$x1*$y1;
$rad2 = 4*$x1+4*$y1;

$rad = 5*5*6;   # the radicand to be reduced.
$rads = $rad**0.5;  # the square root of the radicand.
$int = floor($rads);   # rounding the square root down to the nearest integer.
$crt = "\sqrt($rad)";   # If the conditions of the loop are never met, the default returns to former value. 
$i =$int;   # Counting down from this integer to try reductions on the root.
do { 
$rj = $int**2;      # Checking first for a perfectly square radicand reduction.
if($rj ==$rad) {
$crt = $rad;   # A square root reduction to an integer, i =1 terminates the loop.
$i = 1;
}
$j = $i**2;       #We square the counter, looking to pull the largest square from the root.
$gc = gcd($j,$rad);   # Find the gcd between the squared counter and the radicand.
#elseif ($gc != $j) {
#$k =$i;      # The case of no root reduction, dropping by 1 with each loop to end at i = 1.
#$i = $k-1;
#} 
#else { 
#$rt = $rad/$gc;  # Assuming that gc= j the counter i will be the largest squared value.
#$c = $i;
#$crt =Formula("$c*sqrt($rt)");  # The reduced root.
#$i =1;
until ($i = 1);

$cr1 = $fc*$x1;
$cr2 = $fc*$y1;
$q1 = $fa*$fb;
$q2 = $fa*$cr1;
$q3 = $cr2*$fb;
$qm =$q2-$q3;
$q4 = $cr1*$cr2;
$q5 = $fb*$fb;
$q6 = $fb*$cr1;
$q7 = $fb*$cr1;
$q8 = $cr1*$cr1;
$zab = $q1*$rad1;
$zcd = $q4*$rad2;
$zdg = $q8*$rad2;
$gnum = gcd($zab,$zcd);
$gden = gcd($zab,$zdg);
$zra = $zab/$gnum;
$zrc = $zcd/$gnum;
$zdr = $zab/$gden;
$zdz = $zdg/$gden;
$gc2 = gcd($gnum,$gden);
$nz =$gnum/$gc2;
$dz = $gden/$gc2;
$nz1 = $zrc -$zra;
$dz1 = $zdr-$zdz;
$gc3 = gcd($nz1,$dz1);
$nz2 = $nz1/$gc3;
$dz2 = $dz1/$gc3;
$nz4 =$nz*$nz2;
$dz4 = $dz*$dz2;
$gc4 = gcd($nz4,$dz4);
$nz5 = $nz4/$gc4;
$dz5 = $dz4/$gc4;
$ans4 =$nz5/$dz5;
$ans5 = sprintf("%0.4f",$ans4);

#$d = sqrt($a*$x1+$b*$y1) + sqrt($c*$x1*$y1);

$num = $a/(2*sqrt($a*$x1 + $b*$y1) ) + $c*$y1/(2*sqrt($c*$x1*$y1) );
$denom = $b/(2*sqrt($a*$x1+$b*$y1) ) + $c*$x1/(2*sqrt($c*$x1*$y1) );

$yp = - $num/$denom;

#
## Ok, we are ready to begin the problem...
##
TEXT(beginproblem());


BEGIN_TEXT
$BR
Find the slope of the tangent line to the curve
$BR
\(\displaystyle \sqrt{$a_x +$b_y}  + \sqrt{$c_xy} = 
    \sqrt{\{$a*$x1+$b*$y1\}} + \sqrt{\{$c*$x1*$y1\}} \)
at the point \( ( $x1,$y1 ) \). $BR

The slope is \{ ans_rule(70) \}.

END_TEXT

ANS(num_cmp($yp));

SOLUTION(EV3(<<'END_SOLUTION'));
$PAR SOLUTION $PAR

To find the derivative by implicit differentiation we must apply the notation of `\frac{dy}{dx}` to emphasize that the derivative is applied with respect to the variable of `x`. The terms holding only `x` variables or constants will be treated with our simplified prim tic application of the derivative. But for any term that holds a variable that is not `x`, say for example `y`, then the prime tic we apply for the derivative will take on `\frac{dy}{dx}` to permit the derivative to be applied to `x` implicitly through the variable of `y`. $BR
$BR
The derivative will be a function of two variables, `x` and `y`. We can find the slope of the tangent line by evaluating the derivative, `m = \frac{dy}{dx}` at `x = $x1` at \(y = $y1\). $BR
$PAR
``\begin{aligned}&\\  
\displaystyle \sqrt{$a_x +$b_y}  + \sqrt{$c_xy} &= 
    \sqrt{$rad3} + \sqrt{$rad4}\\  
\displaystyle ($a_x +$b_y)^\frac{1}{2}  + ($c_xy)^\frac{1}{2} &= 
    ($rad3)^\frac{1}{2} + ($rad4)^\frac{1}{2}  && \text{Begin by converting the square roots to rational exponents.}\\  
\displaystyle \left(($a_x +$b_y)^\frac{1}{2}\right)'  + \left(($c_xy)^\frac{1}{2}\right)' &= 
    \left(($rad3)^\frac{1}{2}\right)' + \left(($rad4)^\frac{1}{2}\right)'  && \text{Apply the prime tics for the derivative.}  
\end{aligned}``  $BR
$BR
Provide prime tics for the chain and product rules and include a `\frac{dy}{dx}`  for each prime tic on `y`. $BR
$BR
\(\displaystyle{\left(($a_x +$b_y)^\frac{1}{2}\right)'\left($a_x' +$b_y' \cdot \frac{dy}{dx}\right)  + \left(($c_xy)^\frac{1}{2}\right)' \cdot $c \left(x' \cdot y + x \cdot y' \cdot \frac{dy}{dx}\right)  = \left(($rad3)^\frac{1}{2}\right)' + \left(($rad4)^\frac{1}{2}\right)'}\) $BR
$BR
Apply the derivative at each prime tic.$BR
$BR
\(\displaystyle{\frac{1}{2}($a_x +$b_y)^\frac{-1}{2}\left($a +$b \cdot \frac{dy}{dx}\right)  + \frac{1}{2}($c_xy)^\frac{-1}{2}\cdot $c \left(y + x \cdot \frac{dy}{dx}\right)  = 
    0}\) $BR
$BR
Distribute the constants of `\frac{1}{2}`  and and convert the negative powers into denominator square roots. $BR
$BR
\(\displaystyle{ \frac{1}{ \sqrt{$a_x +$b_y}}\left( \frac{$a}{2} +\frac{$b}{2}  \cdot \frac{dy}{dx}\right)  + \frac{1}{\sqrt{$c_xy}} \frac{$c}{2} \left(y + x \cdot \frac{dy}{dx}\right)  = 
    0}\) $BR
$BR
Reduce. $BR
$BR
\(\displaystyle{ \frac{1}{ \sqrt{$a_x +$b_y}}\left( $fa +$fb  \cdot \frac{dy}{dx}\right)  + \frac{1}{\sqrt{$c_xy}} $fc \left(y + x \cdot \frac{dy}{dx}\right)  = 0}\) $BR
$BR
Distribute: $BR
$BR
\(\displaystyle{ \frac{$fa}{ \sqrt{$a_x +$b_y}} + \frac{$fb}{ \sqrt{$a_x +$b_y}} \cdot \frac{dy}{dx}  + \frac{$fc y}{\sqrt{$c_xy}} + \frac{$fc x}{\sqrt{$c_xy}} \cdot \frac{dy}{dx}  = 0}\) $BR
$BR
Isolate the `\frac{dy}{dx}` terms: $BR
$BR
\(\displaystyle{   \frac{$fb}{ \sqrt{$a_x +$b_y}} \cdot \frac{dy}{dx}   + \frac{$fc x}{\sqrt{$c_xy}} \cdot \frac{dy}{dx}  = -\frac{$fa}{ \sqrt{$a_x +$b_y}} - \frac{$fc y}{\sqrt{$c_xy}}}\) $BR
$BR
Pull the common factor of `\frac{dy}{dx}`: $BR
$BR
\(\displaystyle{  \frac{dy}{dx} \left( \frac{$fb}{ \sqrt{$a_x +$b_y}} + \frac{$fc x}{\sqrt{$c_xy}} \right)  = -\frac{$fa}{ \sqrt{$a_x +$b_y}} - \frac{$fc y}{\sqrt{$c_xy}}}\) $BR
$BR
Isolate`\frac{dy}{dx}`: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = \frac{-\frac{$fa}{ \sqrt{$a_x +$b_y}} - \frac{$fc y}{\sqrt{$c_xy}}}{\frac{$fb}{ \sqrt{$a_x +$b_y}} + \frac{$fc x}{\sqrt{$c_xy}}}}\) $BR
$BR
To clear the minor fractions multiply each minor numerator by the common denominator of `\sqrt{$a_x +$b_y}\cdot \sqrt{$c_xy}`: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = \frac{-\frac{$fa \cdot \sqrt{$a_x +$b_y}\cdot \sqrt{$c_xy}}{ \sqrt{$a_x +$b_y}} - \frac{$fc y \cdot \sqrt{$a_x +$b_y}\cdot \sqrt{$c_xy}}{\sqrt{$c_xy}}}{\frac{$fb \cdot \sqrt{$a_x +$b_y}\cdot \sqrt{$c_xy}}{ \sqrt{$a_x +$b_y}} + \frac{$fc x \cdot \sqrt{$a_x +$b_y}\cdot \sqrt{$c_xy}}{\sqrt{$c_xy}}} }\) $BR
$BR
Cancel the minor denominators with their matching numerator factors: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = \frac{-$fa  \sqrt{$c_xy} - $fc y  \sqrt{$a_x +$b_y}}{$fb  \sqrt{$c_xy}  + $fc x \sqrt{$a_x +$b_y}} }\) $BR
$BR
We will wait on the rationalization of the denominator because we have only to evaluate the derivative at `x = $x1` and `y=$y1` to find the slope at \(y'($x1)\): $BR
$BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{-$fa  \sqrt{$c \cdot $x1 \cdot $y1} - $fc \cdot $y1  \sqrt{$a \cdot $x1 +$b \cdot $y1}}{$fb  \sqrt{$c \cdot $x1 \cdot $y1}  + $fc \cdot $x1 \sqrt{$a \cdot $x1 +$b \cdot $y1}}  }\) $BR
$BR
Reduce radicands:$BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{-$fa  \sqrt{$rad1} - $cr2  \sqrt{$rad2}}{$fb  \sqrt{$rad1}  + $cr1 \sqrt{$rad2}}  }\) $BR
$BR
$BR
To rationalize the denominator and simplify further, multiply the fraction by the number one disguised as denominator's conjugate:$BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{(-$fa  \sqrt{$rad1} - $cr2  \sqrt{$rad2})}{($fb  \sqrt{$rad1}  + $cr1 \sqrt{$rad2})} \cdot \frac{($fb  \sqrt{$rad1}  - $cr1 \sqrt{$rad2})}{($fb  \sqrt{$rad1}  - $cr1 \sqrt{$rad2})} }\) $BR
$BR
Distribute through both quantities:$BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{-$q1  \sqrt{$rad1} \cdot \sqrt{$rad1} + $q2 \sqrt{$rad2} \sqrt{$rad1}-$q3 \sqrt{$rad2} \sqrt{$rad1}  +$q4 \sqrt{$rad2} \sqrt{$rad2}}{($q5  \sqrt{$rad1}\sqrt{$rad1} -$q6 \sqrt{$rad1}\sqrt{$rad2} +$q7 \sqrt{$rad2}\sqrt{$rad1}  - $q8 \sqrt{$rad2} \sqrt{$rad2})}  }\) $BR
$BR
Square identical root products, collect the numerator's like terms and cancel the middle terms of the denominator:$BR
$BR
$BR
\(\displaystyle{ \frac{dy}{dx}  = y'($x1) = \frac{-$q1 \cdot $rad1  + $qm\sqrt{$rad1}\sqrt{$rad2} +$q4 \cdot $rad2 }{$q5  \cdot $rad1  - $q8 \cdot $rad2 } = \frac{-$zab  +$zcd }{$zab  - $zdg }   }\) $BR
$BR
Pull the common factors from the numerator and denominator: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{$gnum (-$zra  +$zrc) }{$gden($zdr  - $zdz) }  }\) $BR
$BR
Reduce and collect constants: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{$nz ($nz1) }{$dz($dz1) } = \frac{$nz ($nz2) }{$dz($dz2) }}\) $BR
$BR
An exact answer for the slope at `x = $x1`: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) = \frac{$nz5 }{$dz5 }}\) $BR
$BR
A decimal approximation for the slope: $BR
$BR
\(\displaystyle{  \frac{dy}{dx}  = y'($x1) \approx $ans5 }\) $BR

$PAR
rad = `$rad`  $BR
int  = `$int` $BR
j = `$j` $BR
rj = `$rj` $BR
i =`$i` $BR
gc = `$gc` $BR
crt = `$crt`$BR
$BR
k = `$k` $BR

END_SOLUTION


ENDDOCUMENT();




In reply to tim Payer

Re: Reducing square roots using if, ifelse nested within a do loop

by Alex Jordan -
It may be relevant to use contextLimitedRadical.pl. Have you looked if it will meet your needs?

https://github.com/openwebwork/pg/blob/master/macros/contextLimitedRadical.pl
In reply to Alex Jordan

Re: Reducing square roots using if, ifelse nested within a do loop

by Alex Jordan -
Nevermind. I see now that you want to automate reducing things like sqrt(12) to 2sqrt(3). contextLimitedRadical.pl will be able to tell the difference between them and count one as right and the other as wrong with an appropriate message, but it can't automatically reduce things like sqrt(12).
In reply to tim Payer

Re: Reducing square roots using if, ifelse nested within a do loop

by Davide Cervone -
First, note that it is elsif not elseif (for no good reason that I know of). Second, an elsif must follow its corresponding if directly (with no intervening commands). You have inserted several assignments between yours.

Your loop might be handled as follows:

for ($i = floor(sqrt($rad)); $i > 1; $i--)  {
  $r = $rad / ($i*$i);
  last if $r == int($r);
}
$crt = ($i == 1 ? "sqrt($rad)" : "$i*sqrt($r)");

A couple of other things to note: your assignment $crt = "\sqrt($rad)"; seems strange to me, since it is neither TeX nor algebra format (did you mean $crt = "\sqrt{$rad}"; or $crt = "sqrt($rad)"; instead?), and since you never actually use $crt, I'm not sure why you need it anyway.

Note that

SOLUTION(EV3(<<'END_SOLUTION'));
$PAR SOLUTION $PAR
can be replaced by
BEGIN_SOLUTION

Finally, you seem to use a lot of variables for intermediate values that complicated the problem in my view. There are two reasons to store something in a variable: you need to use that value several times, or you need to insert the result of a computation into a Compute() string, or the text of the problem (or solution or hint, etc). But it really isn't necessary to use a variable for the second of these, as there are ways to do the computations and have them inserted into the Compute() string or within BEGIN_TEXT/END_TEXT or in PGML.

For example, you can do

$x = Compute("sqrt(".($a*$b).")");
if you want to perform the computation $a*$b and have that inside the square root in the correct answer (if you did compute("sqrt($a*$b)") you would see something like sqrt(4*7) as the correct answer).

For problem text, you can use \{...\} around a computation to get its result inserted into the text:

BEGIN_TEXT
The value of \($a + $b\) is \(\{$a+$b\}\).
END_TEXT
There is no need to make a variable holding $a+$b and substitute that.

Similarly, in PGML you can do

BEGIN_PGML
The value of [`[$a] + [$b]`] is [`[$a+$b]`].
END_PGML
or
BEGIN_PGML
The value of [`[$a] + [$b]`] is [`[@ $a+$b @]`].
END_PGML
So there really is no need to make dozens of variable holding intermediate computations that just clutter up the flow of the problem.
In reply to Davide Cervone

Re: Reducing square roots using if, ifelse nested within a do loop

by tim Payer -
Thank you very much Davide,

I will incorporate all these improvements...

Tim
In reply to tim Payer

Re: Reducing square roots using if, ifelse nested within a do loop

by Davide Cervone -
PS, one other issue I forgot to mention is that your termination condition on the do-loop is incorrect. You probably mean $i == 1 rather than $i = 1. The former tests if $i is 1 or not, and the latter assigns the value 1 to $i (and returns the value 1, so is always considered true, so the loop will stop).

But if you use the loop I suggested, that replaces the do loop anyway.