Below is the code. Thank you for your help.

##############################################

# Initialization

DOCUMENT();

loadMacros(

"PGstandard.pl",

"MathObjects.pl",

"PGcourse.pl",

"AnswerFormatHelp.pl",

"parserFormulaUpToConstant.pl",

);

TEXT(beginproblem());

$showPartialCorrectAnswers = 0;

##############################################

# Setup

Context("Numeric");

# Integrate a*sin(b*x), a and b randomized

$a = Real(non_zero_random(-5,5,1));

$b = Real(non_zero_random(-5,5,1));

$c = Real($a*$b);

$f = FormulaUpToConstant("$a sin($b * x)")->reduce("(-x)-y"=>0,"(-x)+y"=>0);

$dfdx = $f->D; # f'(x)

##############################################

# Main text

Context()->texStrings;

BEGIN_TEXT

Compute the indefinite integral

\[ \int \{$dfdx->TeX\} dx \]

$BR

(remember: your answer should be a function of \(x\)!)

$BR

\{ ans_rule(20) \}

END_TEXT

Context()->normalStrings;

ANS( $f->cmp() );

ENDDOCUMENT();

*The problem displays the derivative*

`f'(x)=(a*b)cos(bx)`

inside the integral
Actually, it is `f'(x) = a*(b*cos(bx))`

, which is structurally different, and it is because of the structural difference that the constants are not combined. The `reduce()`

method would have reduced the constants in your expression, but because the two constants aren't multiplied directly in the derivative, they are not.

The reduction rules don't include anything for this situation. There are more rules that could be added that would help with this but currently there aren't any.
One way around this, however, is to take advantage of the fact that there are no parentheses displayed around the `b*cos(bx)`

in its string version and ask MathObject to parse the value again. Try

$dfdx = Formula($f->D->string);to force the expression to be reparsed, so that the multiplication of the two constants is performed first.

Also, I note that you have used `reduce("(-x)-y"=>0,"(-x)+y"=>0)`

for your formula. But it doesn't contain any sums or differences, so these rules never apply anyway, so there is no need to disable them in this case.

I see you are making `$a`

and `$b`

into Real MathObjects, that is fine, though unnecessary in this problem, since they are only used to be inserted into the formula for `$f`

. You also make a variable `$c`

that is never used, and you force it to a Real as well. Since `$a`

and `$b`

are already Real objects, there is no need to use `Real()`

again on the result, as it will be a Real automatically.

### Re: Simplifying output of automatic differentiation

by Nicholas Nguyen -Thank you both. At this point, the problem still displays formulas like

"-(15cos(3x)),"

but at least it multiplies the coefficients now.

Davide: I ended up keeping the reduction exceptions for $f, because without them, in the solution, WeBWorK might display

"C - 5sin(3x)" instead of "-5sin(3x) + C."

Here is the updated code.

##############################################

# Initialization

DOCUMENT();

loadMacros(

"PGstandard.pl",

"MathObjects.pl",

"PGcourse.pl",

"AnswerFormatHelp.pl",

"parserFormulaUpToConstant.pl",

);

TEXT(beginproblem());

$showPartialCorrectAnswers = 0;

##############################################

# Setup

Context("Numeric");

# Integrate a*sin(b*x), a and b randomized

$a = Real(non_zero_random(-5,5,1));

$b = Real(non_zero_random(-5,5,1));

$c = $a*$b; # Needed for solution display

$f = FormulaUpToConstant("$a sin($b * x)")->reduce("(-x)-y"=>0,"(-x)+y"=>0);

# Without the rules "(-x)-y"=>0,"(-x)+y"=>0, the solution might display "C - sin($ax)."

$dfdx = Formula($f->D->string);

# Reparse so $a and $b are multiplied in display

##############################################

# Main text

Context()->texStrings;

BEGIN_TEXT

Compute the indefinite integral

\[ \int $dfdx \, dx \]

$BR

(remember: your answer should be a function of \(x\)!)

$BR

\{ ans_rule(20) \}

END_TEXT

BEGIN_SOLUTION

Use subtitution with:

\[

u = $b x, \, du = $b dx \implies \frac{1}{$b}du = dx

\]

\[ \int \frac{$c}{$b} \cos(u) \, du = \int $a \cos(u) \, du \]

An antiderivative of \(\cos(u)\) is \(\sin(u)\):

\[

= $a \sin(u) + C

\]

Don't forget to substitute \(u = $b x\):

\[

= $f

\]

END_SOLUTION

Context()->normalStrings;

ANS( $f->cmp() );

ENDDOCUMENT();

### Re: Simplifying output of automatic differentiation

by Nicholas Nguyen -"-15cos(3x)"

in the problem now. Here's the rewrite:

##############################################

# Initialization

DOCUMENT();

loadMacros(

"PGstandard.pl",

"MathObjects.pl",

"PGcourse.pl",

"AnswerFormatHelp.pl",

"parserFormulaUpToConstant.pl",

);

TEXT(beginproblem());

$showPartialCorrectAnswers = 0;

##############################################

# Setup

Context("Numeric");

Context()->variables->add(u=>"Real");

# Integrate a*sin(u), with u=b*x a and b randomized

$a = Real(non_zero_random(-5,5,1));

$b = Real(non_zero_random(-5,5,1));

$c = $a*$b; # Needed for solution display

# Define $u = b*x as a formula of x for substitution

$u = Formula("$b x");

$f = FormulaUpToConstant("$a sin(u)")->reduce("(-x)-y"=>0,"(-x)+y"=>0);

# Without the rules "(-x)-y"=>0,"(-x)+y"=>0, the solution might display "C - sin($ax)."

$dfdu = Formula($f->D('u')); # df/du

$dfdux = $dfdu->substitute(u=>$u)->reduce; # Substitute u = $b*x into df/du

$dudx = Formula($u->D('x'))->reduce; # du/dx

$dfdx = Formula($dfdux*$dudx); # Chain rule df/du * du/dx = df/dx

$dfdxr = Formula($dfdx->reduce->string)->reduce; # Simplify

# In $dfdxr, first reduce moves coefficients outside cosine to left, but doesn't multiply

# Next, use string to multiply coefficients. This puts coefficient (with negative sign) in parentheses

# Finally, second reduce gets rid of excess parentheses around coefficient

##############################################

# Main text

Context()->texStrings;

BEGIN_TEXT

Compute the indefinite integral

\[ \int $dfdxr \, dx \]

$BR

(remember: your answer should be a function of \(x\)!)

$BR

\{ ans_rule \}

END_TEXT

BEGIN_SOLUTION

Use subtitution with:

\[

u = $b x, \, du = $b dx \implies \frac{1}{$b}du = dx

\]

\[ \int \frac{$c}{$b} \cos(u) \, du = \int $a \cos(u) \, du \]

An antiderivative of \(\cos(u)\) is \(\sin(u)\):

\[

= $a \sin(u) + C

\]

Don't forget to substitute \(u = $b x\):

\[

= $f

\]

END_SOLUTION

Context()->normalStrings;

ANS( $f->cmp() );

ENDDOCUMENT();

I have been finding this series of posts helpful for something I’ve been working on. I suspect another manifestation of this problem is illustrated by the code below.

Like Nicholas, the output I get has an extra pair of parentheses, namely:

-(sqrt(2x+3) ) +2 instead of -sqrt(2x+3) +2. The issue only seems to arise when $parent = sqrt(x). If $parent is 1/x or x^2 for example, there is no issue of extra parentheses.

~Mary

DOCUMENT();

loadMacros(

"PGstandard.pl", #
Standard macros for PG language

"MathObjects.pl",

);

TEXT(beginproblem());

Context("Numeric");

$a = -1;
#non_zero_random(-3, 3, 1);
# vertical stretch and reflection

$b = non_zero_random(-2, 2, 1); # horizontal stretch and reflection

$c = random(-4, 4, 1); # horizontal
shift

$d = random(-4, 4, 1); # vertical shift

Context() -> flags -> set ( reduceConstants => 0,
reduceConstantFunctions => 0 );

$parent = Formula("sqrt(x)");

$fx =$parent ->substitute(x => "$b * x -
$c") -> reduce ("(-x)-y" => 0, " x-(-y)" =>
0, "(-x)+y" =>0);

$fxy = Formula("$a * $fx + $d") -> reduce(
"(-x)-y" => 0, "(-x)+y" =>0, "-a" =>
0 );

Context()->texStrings;

BEGIN_TEXT

Given the function \(
f(x) = \displaystyle $fxy \) and
its parent function \( y = \displaystyle
$parent\), mid-formula is \( y = \displaystyle $fx \)

END_TEXT

ENDDOCUMENT();

*I get has an extra pair of parentheses, namely:*

`-(sqrt(2x+3))+2`

instead of `-sqrt(2x+3)+2`

.Your issue turns out to be from a different cause. The MathObjects library adds extra parentheses in its output to try to make it painfully clear to the student what the structure of the expression is. For example, sin(x)^2 is shown as [sin(x)]^2 so it is clear that the whole expression is squared, not just the x.

Your situation is coming from that process. You can do

Context()->operators->set(fn => {parenPrecedence => 6.5})to fix this. (The

`parenPrecedence`

tells when extra parens are added around functions based on the precedence of the operator that surrounds them. 6.5 puts it between the precedence of unary minus and exponentiation, so that you still get [sin(x)]^2 but not -[sin(x)].)
I give you a modified version of your problem below. There are several small changes. One thing to keep in mind is that the names of the reduction formulas must be given exactly, so your `" x-(-y)"`

(which has an extra leading space) does nothing. In any case, I don't think you want that one since, you *do* want `x-(-3)`

to be converted to `x+3`

, I assume. (Your `$c`

can be negative in `"$b * x - $c"`

).

Similarly, your `"-a"=>0`

specification does nothing since there is no rule with the name `"-a"`

. Did you mean `"-n"`

? In any case, I would not recommend that you remove that one in this case. The `parenPrecedence`

is what is needed, here.

So here is the modified version:

loadMacros( "PGstandard.pl", # Standard macros for PG language "MathObjects.pl", ); TEXT(beginproblem()); Context("Numeric"); $a = -1; #non_zero_random(-3, 3, 1); # vertical stretch and reflection $b = non_zero_random(-2, 2, 1); # horizontal stretch and reflection $c = random(-4, 4, 1); # horizontal shift $d = random(-4, 4, 1); # vertical shift Context()->operators->set(fn => {parenPrecedence => 6.5}); Context()->reduction->noreduce("(-x)-y","(-x)+y"); $parent = Formula("sqrt(x)"); $fx = $parent->substitute(x => "$b * x - $c")->reduce; $fxy = Formula("$a * $fx + $d")->reduce; Context()->texStrings; BEGIN_TEXT Given the function \(f(x) = $fxy\) and its parent function \(y = $parent\), the mid-formula is \(y = $fx\) END_TEXT

*I ended up keeping the reduction exceptions for $f, because without them, in the solution, WeBWorK might display "C - 5sin(3x)" instead of "-5sin(3x) + C."*

Right. I forgot that you were using `FormulaUpToConstant()`

and that it does introduce an addition.

*At this point, the problem still displays formulas like
"-(15cos(3x)),"*

OK, I've handled this by adjusting the reduction rules a little further. In the code below, I added

Context()->reduction->noreduce("(-x)-y","(-x)+y","(-x)*y","x*(-y)");which removes the rules that factor out negatives from sums, additions, and products (it is the latter that is causing your issues, here).

I also added `reduce`

to the definition of `$dfdx`

. Without this, you would end up with "(-15)cos(3x)".

So here is my modified version:

DOCUMENT(); loadMacros( "PGstandard.pl", "MathObjects.pl", "PGcourse.pl", "AnswerFormatHelp.pl", "parserFormulaUpToConstant.pl", ); TEXT(beginproblem()); $showPartialCorrectAnswers = 0; ############################################## # Setup Context("Numeric"); Context()->reduction->noreduce("(-x)-y","(-x)+y","(-x)*y","x*(-y)"); # Integrate a*sin(b*x), a and b randomized $a = Real(non_zero_random(-5,5,1)); $b = Real(non_zero_random(-5,5,1)); $c = $a*$b; # Needed for solution display $f = FormulaUpToConstant("$a sin($b * x)")->reduce; $dfdx = Formula($f->D->string)->reduce; # Reparse so $a and $b are multiplied in display ############################################## # Main text Context()->texStrings; BEGIN_TEXT Compute the indefinite integral \[ \int $dfdx \, dx \] (remember: your answer should be a function of \(x\)!) $BR \{ ans_rule(20) \} END_TEXT BEGIN_SOLUTION Use subtitution with: \[u = $b x, \, du = $b dx \implies \frac{1}{$b}du = dx\] \[\int \frac{$c}{$b} \cos(u) \, du = \int $a \cos(u) \, du\] An antiderivative of \(\cos(u)\) is \(\sin(u)\): \[= $a \sin(u) + C\] Don't forget to substitute \(u = $b x\): \[= $f\] END_SOLUTION Context()->normalStrings; ANS($f->cmp); ENDDOCUMENT();