physicsdiff.mpl Version 0.3

This procedure allows you to perform a first variation of some expression (presumed to be inside an integral, e.g. the Lagrangian density in an action). It will differentiate the expression treating the specified function as the differentiation parameter, with the additional feature that it automatically attempts to integrate first order derivatives of that function by parts.

It now should work for derivatives up to order 10. This can be easily changed in the mpl file should you need greater. It should also work for derivatives inside of nasty functions, provided Maple can compute the regular differential of that function.

To call the procedure, run: physicsdiff(expression,function,diffparam);

Example


expr := h(r)*g(r)*2 + h(r)*diff(h(r),r)^2*3 + diff(h(r),r):
physicsdiff(expr,h(r),r);
	2*g(r) + 3*(diff(h(r),r))^2 - 2*diff(3*h(r)*diff(h(r),r),r)

Source Code


#This maple procedure does a functional variation, much like diff does when used
#with(Physics):, but with the added feature that it can vary simple derivatives
#with respect to that function, ie. vary(c*diff(f(r),r)^2,f(r)) using
#integration by parts.
global MAXIMUM_NUMBER_OF_DERIVATIVES := 10;

_physicsdiff_term := proc(expr,function,term,dparam)
	local counter,counter2,tmp,retterm,_physicsdiff_innervar;
	retterm := 0;

	if is(op(0,dparam)=`list`) then
		for counter from 1 to nops(dparam) do
			#tmp := term;
			for counter2 from 1 to MAXIMUM_NUMBER_OF_DERIVATIVES do
				tmp := subs(diff(function,dparam[counter]$counter2)=_physicsdiff_innervar(dparam[counter]),term);
				retterm := retterm + (-1)^(counter2)*diff(subs(_physicsdiff_innervar(dparam[counter]) = diff(function,dparam[counter]$counter2),Physics:-diff(tmp,_physicsdiff_innervar(dparam[counter]))),dparam[counter]$counter2);
			end do:
		end do:
		#print("Retterm:",retterm);
		RETURN(retterm);
	else
		#tmp := term;
		for counter2 from 1 to MAXIMUM_NUMBER_OF_DERIVATIVES do
			tmp := subs(diff(function,dparam$counter2)=_physicsdiff_innervar(dparam),term);
			#print("tmp:",tmp);
			retterm := retterm + (-1)^(counter2)*diff(subs(_physicsdiff_innervar(dparam) = diff(function,dparam$counter2),Physics:-diff(tmp,_physicsdiff_innervar(dparam))),dparam$counter2);
		end do:
		#print("Retterm:",retterm);
		RETURN(retterm);
	fi:

end proc:




physicsdiff := proc(expr,function,dparam)
	local expr2,newexpr,exprlength,term,tmp,counter;
	description "This Maple procedure will perform a physicists' functional differentiation, neglecting boundary terms and integrating by parts to functionally vary an expression with respect to a function, even if it contains powers of first derivatives of that function. Written by W. Brenna, Sept 3 2012. Version 0.2.";

	if not(is(op(0,f(r)*g(r))=`*`)) then
		print("Error: Conflicting package detected! The `*` declaration has been redefined and results are therefore unreliable. Make sure you have loaded physicsdiff before running with(Physics).");
		RETURN(expr);
	fi:
	if assigned(makeg) then
		print("Error: Conflicting package detected! GRTensor overwrites a number of variables that can cause physicsdiff to perform in unstable ways. Please use physicsdiff before running grtw().");
		RETURN(expr);
	fi:


	expr2 := expand(expr);
	exprlength := nops(expr2);


	#newexpr := expr2;
	newexpr := 0;


	if is(op(0,expr2)=`+`) then
		for counter from 1 to exprlength do
			term := op(counter,expr2);
#This just does the first order integration by parts.
			newexpr := newexpr + _physicsdiff_term(newexpr,function,term,dparam):
		end do:
	else
		term := expr2;
		newexpr := newexpr + _physicsdiff_term(newexpr,function,term,dparam):
	fi:

#Finally, we do the regular differentiation by parts to build up the final
#terms.
	#RETURN(newexpr + frontend(diff,[expr2,function]));
#frontend is hopeless for this - non-integer powers make it cry.
	#print(Physics:-diff(expr2,function));
	#print(newexpr,Physics:-diff(expr2,function));
	RETURN(newexpr + Physics:-diff(expr2,function));

end proc: