[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Perl or Python?



On Tue, 24.03.2009 15:27:45 , Alexey Pechnikov wrote:
> Hello!
> 
> On Tuesday 24 March 2009 12:19:46 Тихон Тарнавский wrote:
> > > И что в этом примере интересного - подстановка табличных интергралов? Это
> > > то же самое, что автодополнение в текстовом редакторе.
> >
> > Похоже, Артём был прав, что "малость не оценят". Если по-Вашему,
> > символьное дифферинцирование сводится к подстановке табличных
> > производных (а не интегралов), то я совершенно правильно этот пример
> > всё-таки не показал, и даже зря упомянул: умаялся бы объяснять. 
> 
> Мне интереснее интегрирование. Можете представить пример аналитического 
> вычисления интеграла пуассона от нуля до бесконечности? Естественно, 
> интересует не ответ из справочника, а все преобразования по шагам.
Повторяю: учебный пример, о котором я говорил, -- это функция
символьного _дифференцирования_. Я писал её для учебного цикла статей,
который публиковался в июле-декабре 2006 года. С тех пор максимой не
занимался, и никаких новых примеров сейчас выдумывать не буду -- мне
это не интересно. Хотел показать то, что уже есть -- и только.

> > Если в
> > двух словах... Гораздо важнее дифференцирование выражений: суммы,
> > частного, произведения и композиции функций. А самое важное --
> > обработка _произвольной_ степени вложенности этих выражений в любых
> > комбинациях. Ну и туда же вычисление производных произвольного
> > порядка, включая частные по любой заданной переменной; но это уже
> > мелочи. 
> 
> А если без фантазий, то все сводится к довольно тупым преобразованиям, и ни о 
> какой произвольной степени вложенности речи не идет. Насчет частных 
> производных тоже сильно сомневаюсь, разве что от степенных функций. Если не 
> согласны, покажите, как получить аналитическое решение диффузионного уравнения 
> при заданной правой части и граничных условиях.
Не понял, какие фантазии? Вы не допускаете возможности символьного
вычисления производных от выражения произвольной степени вложенности с
помощью рекурсии? Ну так смотрите во вложении. Только учтите, что это
_учебный_ пример. Некоторые места сознательно написаны сложнее, чтобы
показать конкретные приёмы; некоторые места сознательно написаны ближе
к императивному стилю для облегчения восприятия всего примера; в том
же файле есть одна или две небольших функции, которые в самой функции
дифференцирования не используются.

-- 
С уважением,
Тихон Тарнавский.
http://linuxforum.ru
http://posix.ru
mapany(f,[lst]):=block([o,l],l:lst,
  if length(setify(map(length,l)))>1 then
    error("Arguments to mapany are not of the same length"),
  o:op(l[1]),
  for i:1 thru length(l) do
    l[i]:subst("[",op(l[i]),l[i]),
  subst(o,"[",apply(map,cons(f,l)))
)$
map1st(f,expr,x):=block([o],
  o:op(expr),
  subst(o,"[",map(f,subst("[",o,expr),makelist(x,i,1,length(expr))))
)$
index(expr,list):=block([num],
  num:for i:1 thru length(list) do
      if equal(expr,list[i]) then
        return(i),
  if integerp(num) then num
)$
setup_autoload(stringproc,sequal)$
sindex(expr,list):=block([num],
  num:for i:1 thru length(list) do
      if sequal(expr,list[i]) then
        return(i),
  if integerp(num) then num
)$
smember(expr,list):=
  if sequal(true,
    for i in list do
      if sequal(expr,i) then
        return(true) )
  then true$

deriv([l]):=block([f,len,o,x,func,fdrv],
  len:length(l),
  if len=0 then
    error("deriv can't be used without arguments"),
  f:l[1],
  x:listofvars(f),
  /*display(f),*/
  if len=1 then (
    if length(x)=0 then
      return(0),
    if length(x)>1 then
      error("Expression has more than one unknowns and none was specified.",
        "Unknowns given:", x),
    x:x[1] )
  else
    x:l[2],
  if len=3 then (
    integerp(l[3]) or
      return('diff(x,l[3])),
    if l[3]=0 then
      return(f),
    if l[3]<0 then
      error("Improper count to deriv:",l[3]),
    if l[3]>1 then
      return(deriv(deriv(f,x,l[3]-1),x))
  ),
  if len>3 then (
    if(evenp(len)) then
      l:endcons(1,l),
    return(deriv(apply(deriv,rest(l,-2)),l[len],l[len+1]))
  ),
  if atom(f) or subvarp(f) then
    if f=x then
      return(1)
    else
      return(0),
  o:op(f),
  func:[sqrt,sin,cos,abs,exp,log,tan,cot,sec,csc,asin,acos,atan,acot,asec,acsc,
    sinh,cosh,tanh,coth,asinh,acosh,atanh,acoth,asech,acsch],
  fdrv:[1/2/arg,cos(arg),-sin(arg),arg/abs(arg),exp,1/arg,sec(arg)^2,-csc(arg)^2,
    tan(arg)*sec(arg),-cot(arg)*csc(arg),1/sqrt(1-arg^2),-1/sqrt(1-arg^2),
    1/(1+arg^2),-1/(1+arg^2),1/arg^2/sqrt(1-1/arg^2),-1/arg^2/sqrt(1-1/arg^2),
    cosh(arg),sinh(arg),sech(arg),-csch(arg),1/sqrt(arg^2+1),1/sqrt(arg^2-1),
    1/(1-arg^2),1/(1-arg^2),-1/arg^2/sqrt(1/arg^2-1),-1/arg^2/sqrt(1/arg^2+1)],
  if sequal(o,"+") or sequal(o,"[") or sequal(o,set) then
    map1st(deriv,f,x)
  else if sequal(o,"-") then
    -deriv(-f,x)
  else if sequal(o,"*") then
    deriv(first(f),x)*rest(f)+first(f)*deriv(rest(f),x)
  else if sequal(o,"//") then
    (deriv(first(f),x)*last(f)-first(f)*deriv(last(f),x))/last(f)^2
  else if sequal(o,"^") then
    first(f)^last(f)*log(first(f))*deriv(last(f),x)+
      first(f)^(last(f)-1)*last(f)*deriv(first(f),x)
  else if smember(o,func) then
    deriv(first(f),x)*subst(first(f),arg,fdrv[sindex(o,func)])
  else
    'diff(f,x)
)$

Reply to: