# Question:Signs of first and second derivatives of bivariate function: fdiff() vs D[]()

## Question:Signs of first and second derivatives of bivariate function: fdiff() vs D[]()

Maple 2024

I have a complicated bivariate function f(Gamma,rho) that is a RootOf of a quartic. I know that it is strictly positive (one of the four roots at least) for Gamma=0..10 and rho in (-1,+1), with bounds excluded.

I need to find the signs of its first and second derivatives (wrt to Gamma and wrt to rho: 4 derivatives in total).

I encounter numerical issues when I plot3d the derivatives using D[]() vs. fdiff() (numerical function evaluations of the RootOf). I was hoping for the two commands to produce the same output, but they don't it seems. What's going on?

Script:

 > restart; _quartic := RootOf(-8*(rho + 1)^4*_Z^4 + 12*(rho + 1)^3*Gamma*(rho - 1)*_Z^3 - 5*(rho + 1)^2*(-4/5 + Gamma^2*rho^2 + 2*(-2/5 - Gamma^2)*rho + Gamma^2)*_Z^2 - 4*(rho + 1)*Gamma*(rho^2 - 1)*_Z + Gamma^2*(rho + 1)*(rho - 1)^2); convert(_quartic,radical): f(Gamma,rho) := simplify(%):
 (1)

Synthetic representation of derivatives

 > der1_Gamma := diff(_quartic, Gamma): der1_rho := diff(_quartic, rho): Diff('f(Gamma,rho)', Gamma) = collect~(normal(eval(der1_Gamma, _quartic = 'f(Gamma,rho)')), 'f(Gamma,rho)'); Diff('f(Gamma,rho)', rho) = collect~(normal(eval(der1_rho, _quartic = 'f(Gamma,rho)')), 'f(Gamma,rho)'); der2_Gamma := diff(der1_Gamma, Gamma): der2_rho := diff(der1_rho, rho): Diff('f(Gamma,rho)', Gamma\$2) = collect~(normal(eval(der2_Gamma, _quartic = 'f(Gamma,rho)')), 'f(Gamma,rho)'); Diff('f(Gamma,rho)', rho\$2) = collect~(normal(eval(der2_rho, _quartic = 'f(Gamma,rho)')), 'f(Gamma,rho)');
 (2)

Signs of derivatives: fdiff (numerical function evaluations of the RootOf) vs. D[]()

 > restart; with(plots):
 > _quartic := RootOf(-8*(rho + 1)^4*_Z^4 + 12*(rho + 1)^3*Gamma*(rho - 1)*_Z^3 - 5*(rho + 1)^2*(-4/5 + Gamma^2*rho^2 + 2*(-2/5 - Gamma^2)*rho + Gamma^2)*_Z^2 - 4*(rho + 1)*Gamma*(rho^2 - 1)*_Z + Gamma^2*(rho + 1)*(rho - 1)^2):
 > plot3d(_quartic, Gamma=0..10, rho=-1..+1, labels=[Gamma,rho,Lambda(Gamma,rho)],axesfont=["helvetica","roman",20],labelfont=["helvetica","roman",30]);

Define it as a f and test it for Gamma=1 and rho=0.5

 > f := (Gamma,rho) -> RootOf(-8*(rho + 1)^4*_Z^4 + 12*(rho + 1)^3*Gamma*(rho - 1)*_Z^3 - 5*(rho + 1)^2*(-4/5 + Gamma^2*rho^2 + 2*(-2/5 - Gamma^2)*rho + Gamma^2)*_Z^2 - 4*(rho + 1)*Gamma*(rho^2 - 1)*_Z + Gamma^2*(rho + 1)*(rho - 1)^2): evalf(f(1.0,0.5));
 (3)

Value at zero:

 > f(0,0): allvalues(%): fl := select(is, [allvalues(f(0,0))], positive)[];evalf(%);
 (4)

Value at infinity (commented out because too slow)

 > #limit(f(x,y), {x = infinity, y = 0}): #fh := select(is, [allvalues(%)], positive)[];evalf(%);

Derivative at zero:

 > allvalues([D[1](f)(0,0)]): Dfl := %[1][];
 (5)

Derivative at a point, evaluated, vs numerical derivative at a point:

 > D[1](f)(1,0.5): evalf(%); fdiff(f(x,y), x, {x = 1.0, y = 0.5}); fdiff(f, [1], [1.0,0.5]); D[2](f)(1,0.5): evalf(%); fdiff(f(x,y), y, {x = 1.0, y = 0.5}); fdiff(f, [2], [1.0,0.5]);
 (6)

Can make a function out of fdiff

 > fDfG := (Gamma,rho) -> fdiff(f, [1], [Gamma,rho]); fDfr := (Gamma,rho) -> fdiff(f, [2], [Gamma,rho]);
 (7)

Check for numerical values close to thresholds:

 > Digits := 15: evalf('D[1]'(f)(0.1e-8,0.5));fdiff(f, [1], [0.1e-8,0.5]); evalf('D[1]'(f)(0.1e-7,0.5));fdiff(f, [1], [0.1e-7,0.5]); evalf('D[1]'(f)(0.1e-5,0.5));fdiff(f, [1], [0.1e-5,0.5]); evalf('D[1]'(f)(0.00001,0.5));fdiff(f, [1], [0.00001,0.5]); evalf('D[1]'(f)(0.001,0.5));fdiff(f, [1], [0.001,0.5]); evalf('D[2]'(f)(1,-0.99));fdiff(f, [2], [1,-0.99]); evalf('D[2]'(f)(1,-0.97));fdiff(f, [2], [1,-0.97]); evalf('D[2]'(f)(1,-0.1));fdiff(f, [2], [1,-0.1]); evalf('D[2]'(f)(1,0.98));fdiff(f, [2], [1,0.98]); evalf('D[2]'(f)(1,-0.99));fdiff(f, [2], [1,-0.99]);
 (8)

Compare with D (vertical range here to prevent effect of large values from fdiff near zero):

 > d1G := plot3d([D[1](f), fDfG], 0..10, -0.95..+0.95, view=-0.3..0, color = [red, blue]); d1r := plot3d([D[2](f), fDfr], 0..10, -0.95..+0.95, color = [red, blue]);

Second derivatives:

 > evalf('D[1,1]'(f)(1.0,0.5)); fdiff(f, [1, 1], [1.0,0.5]); evalf('D[2,2]'(f)(1.0,0.5)); fdiff(f, [2, 2], [1.0,0.5]); fD2fG := (Gamma,rho) -> fdiff(f, [1, 1], [Gamma]); fD2fr := (Gamma,rho) -> fdiff(f, [2, 2], [Gamma]);
 (9)
 > d2G:= plot3d([D[1,1](f), fD2fG], 0..10, -0.9..+0.9, color = [red, blue]); d2r:= plot3d([D[2,2](f), fD2fr], 0..10, -0.9..+0.9, color = [red, blue]);
 > d1d2G := plot3d([fDfG, fD2fG], 0.1e-6 .. 10, -0.98 .. +0.98, axesfont=["helvetica","roman",20],labelfont=["helvetica","roman",30], size=[1000,1000]); d1d2r := plot3d([fDfr, fD2fr], 0.1e-6 .. 10, -0.98 .. +0.98, axesfont=["helvetica","roman",20],labelfont=["helvetica","roman",30], size=[1000,1000]);

Download signs_derivatves_bivariate.mw

﻿