diff --git a/packages/doenetml-worker/src/components/FunctionOperators.js b/packages/doenetml-worker/src/components/FunctionOperators.js
index f1fc05a0b..50e1731cb 100644
--- a/packages/doenetml-worker/src/components/FunctionOperators.js
+++ b/packages/doenetml-worker/src/components/FunctionOperators.js
@@ -614,9 +614,12 @@ export class Derivative extends FunctionBaseOperator {
]);
} else {
for (let variable of dependencyValues.derivVariables) {
- value = value.derivative(
- variable.subscripts_to_strings().tree,
- );
+ value = value
+ .normalize_applied_functions()
+ .derivative(
+ variable.subscripts_to_strings()
+ .tree,
+ );
}
}
return value.strings_to_subscripts();
diff --git a/packages/doenetml-worker/src/test/tagSpecific/functionoperators.test.ts b/packages/doenetml-worker/src/test/tagSpecific/functionoperators.test.ts
index 724e076de..49aac3b81 100644
--- a/packages/doenetml-worker/src/test/tagSpecific/functionoperators.test.ts
+++ b/packages/doenetml-worker/src/test/tagSpecific/functionoperators.test.ts
@@ -303,7 +303,7 @@ describe("Function Operator tag tests", async () => {
await check_items({ a, b, c, x, x1, x2 });
});
- async function checkd_list(core: Core) {
+ async function check_list(core: Core) {
const stateVariables = await returnAllStateVariables(core);
expect(
stateVariables["/d1"].stateValues.formula.equals(me.fromText("2x")),
@@ -424,6 +424,7 @@ describe("Function Operator tag tests", async () => {
expect(d12(x)).closeTo(0, 1e-10);
}
}
+
it("derivative 2", async () => {
let core = await createTestCore({
doenetML: `
@@ -456,7 +457,7 @@ describe("Function Operator tag tests", async () => {
`,
});
- await checkd_list(core);
+ await check_list(core);
});
it("derivative 2, labeled", async () => {
@@ -491,7 +492,7 @@ describe("Function Operator tag tests", async () => {
`,
});
- await checkd_list(core);
+ await check_list(core);
const stateVariables = await returnAllStateVariables(core);
@@ -518,6 +519,43 @@ describe("Function Operator tag tests", async () => {
expect(stateVariables["/d14"].stateValues.label).eq("d14");
});
+ it("derivative of trig functions raised to powers", async () => {
+ const core = await createTestCore({
+ doenetML: `
+ sin(x)^2
+ sin^2(x)
+ tan(x)^3
+ tan^3(x)
+ $f1
+ $f1a
+ $f2
+ $f2a
+ `,
+ });
+
+ const stateVariables = await returnAllStateVariables(core);
+ expect(
+ stateVariables["/d1"].stateValues.formula.equals(
+ me.fromText("2 sin(x) cos(x)"),
+ ),
+ ).be.true;
+ expect(
+ stateVariables["/d1a"].stateValues.formula.equals(
+ me.fromText("2 sin(x) cos(x)"),
+ ),
+ ).be.true;
+ expect(
+ stateVariables["/d2"].stateValues.formula.equals(
+ me.fromText("3 tan^2(x) sec^2(x)"),
+ ),
+ ).be.true;
+ expect(
+ stateVariables["/d2a"].stateValues.formula.equals(
+ me.fromText("3 tan^2(x) sec^2(x)"),
+ ),
+ ).be.true;
+ });
+
it("specifying derivative variables of a function", async () => {
let core = await createTestCore({
doenetML: `