代数操作その2:中置記法による代数操作:問題2.58a
問題2.58aは順番が変わるだけで簡単。
人間にはだいぶ見やすくなるなあ。
ただ2.58bはなんか切りがなくて、あまり興味も持てないのでパス。
----
//sum?
const
bool isSum(const List& x)
{return(isPair(x)
&& isEq("+",cadr(x)));}
//addend
const
List addend(const List& x)
{return(car(x));}
//augend
const
List augend(const List& x)
{return(caddr(x));}
//make-sum
const
List makeSum(const List& a1, const List& a2)
{
if(isEqNumber(a1,0)){return(a2);}
else if(isEqNumber(a2,0)){return(a1);}
else
if(isNumber(a1)&&isNumber(a2)){return(a1+a2);}
return(makeExpression(a1,"+",a2));
}
//product?
const
bool isProduct(const List& x)
{return(isPair(x)
&& isEq("*",cadr(x)));}
//multiplier
const
List multiplier(const List& x)
{return(car(x));}
//multoplicand
const
List multiplicand(const List& x)
{return(caddr(x));}
//make-product
const
List makeProduct(const List& m1, const List& m2)
{
if(isEqNumber(m1,0)||isEqNumber(m2,0)){return(makeNumber(0));}
else if(isEqNumber(m1,1)){return(m2);}
else if(isEqNumber(m2,1)){return(m1);}
else
if(isNumber(m1)&&isNumber(m2)){
return(m1*m2);
}else if(isNumber(m2)){
return(makeExpression(m2,"*",m1));
}
return(makeExpression(m1,"*",m2));
}
//exponentiation?
const
bool isExponentiation(const List& x)
{return(isPair(x)
&& isEq("**",cadr(x)));}
//base
const
List base(const List& x)
{return(car(x));}
//exponent
const
List exponent(const List& x)
{return(caddr(x));}
//make-sum
const
List makeExponentiation(const List& b, const List& e)
{
if(isEqNumber(b,0)){return(makeNumber(0));}
else
if(isEqNumber(e,0)){return(makeNumber(1));}
else if(isEqNumber(e,1)){return(e);}
else if(isNumber(e)&&isNumber(b)){
return(power(b,e));
}
return(makeExpression(b,"**",e));
}
//---------abstraction
barrier---------
//deriv
const
List derivative(const List& expression,
const List& variable)
{
if(isNumber(expression)){return(makeNumber(0));}
else if(isVariable(expression)){
if(isSameVariable(expression,variable)){
return(makeNumber(1));
}else{
return(makeNumber(0));
}
}else if(isSum(expression)){
return(makeSum
(derivative(addend(expression),variable),
derivative(augend(expression),variable)));
}else if(isProduct(expression)){
return(makeSum
(makeProduct
(multiplier(expression),
derivative(multiplicand(expression),variable)),
makeProduct
(derivative(multiplier(expression),variable),
multiplicand(expression))));
}else if(isExponentiation(expression)){
return(makeProduct
(exponent(expression),
makeProduct
(makeExponentiation
(base(expression),
exponent(expression)+makeNumber(-1)),
derivative(base(expression),variable))));
}
cerr<<"unknown exoression type
--- DERIV "<<expression<<endl;
return(makeExpression());
}
template<typename
LeafType>
const
List derivative(const List& expression,
const LeafType& variable)
{return(derivative(expression,makeSymbol(variable)));}
int
main(int argc, char** argv)
{
const string variable("x");
const auto
polynomial1(makeExpression("x","+",3));
cout<<"(deriv
"<<expString(polynomial1)
<<"
"<<variable<<")="
<<expString(derivative(polynomial1,variable))<<endl;
const auto
polynomial2(makeExpression("x","*","y"));
cout<<"(deriv
"<<expString(polynomial2)
<<"
"<<variable<<")="
<<expString(derivative(polynomial2,variable))<<endl;
const auto polynomial3
(makeExpression
(makeExpression("x","*","y"),"*",
makeExpression("x","+",3)));
cout<<"(deriv
"<<expString(polynomial3)
<<"
"<<variable<<")="
<<expString(derivative(polynomial3,variable))<<endl;
const auto polynomial4
(makeExpression("x","**","4"));
cout<<"(deriv
"<<expString(polynomial4)
<<"
"<<variable<<")="
<<expString(derivative(polynomial4,variable))<<endl;
const auto polynomial5
(makeExpression(makeExpression("x","**","4"),"+",
makeExpression
(3,"*",makeExpression("x","**",3))));
cout<<"(deriv
"<<expString(polynomial5)
<<"
"<<variable<<")="
<<expString(derivative(polynomial5,variable))<<endl;
return(0);
}
----
出力
----
(deriv
(x + 3) x)=1
(deriv
(x * y) x)=y
(deriv
((x * y) * (x + 3)) x)=((x * y) + (y * (x + 3)))
(deriv
(x ** 4) x)=(4 * (x ** 3))
(deriv
((x ** 4) + (3 * (x ** 3))) x)=((4 * (x ** 3)) + (3 * (3 * (x ** 2))))
0 件のコメント :
コメントを投稿