从MATLAB到R的fzero函数

时间:2017-05-15 08:39:12

标签: r matlab

我想使用R的fzero函数来查找函数的根。问题变得复杂,因为所讨论的函数调用了一些其他函数,而这些函数又调用另一个函数。我确实有MATLAB代码执行它,我试图将其转换为R,但不能在工作中。我对MATLAB的经验是有限的,所以我很可能在翻译时错过了MATLAB代码的一些功能。我的最终目标是获得R的工作等效MATLAB代码。任何提示都将受到高度赞赏!

我得到的错误是函数psi(): (-t(I)* pi ^ 2)%*%time中的错误:不一致的参数 虽然矩阵的大小确实匹配,但这部分代码在隔离运行时可以使用一些天真的输入。

注意:我曾尝试在某些地方使用mrdivide(R相当于MATLAB的右矩阵除法),但没有效果。

NB2:我尝试使用uniroot代替fzero时遇到同样的错误。

# Global parameters:
N  = 140
A2 = (256 times 256) matrix with data
I  = vector of size 256: (0, 1, 2^2, 3^2, 4^2, ..., 255^2)

# ----------------------------------------------------------------
MATLAB working code:
fzero( @(t)(t-evolve(t)),[0,0.1])

function  [out,time]=evolve(t)
global N
Sum_func = func([0,2],t) + func([2,0],t) + 2*func([1,1],t);
time=(2*pi*N*Sum_func)^(-1/3);
out=(t-time)/time;
end

function out=func(s,t)
global N
if sum(s)<=4
Sum_func=func([s(1)+1,s(2)],t)+func([s(1),s(2)+1],t); const=
(1+1/2^(sum(s)+1))/3;
time=(-2*const*K(s(1))*K(s(2))/N/Sum_func)^(1/(2+sum(s)));
out=psi(s,time);
else
out=psi(s,t);
end
end

function out=psi(s,Time)
global I A2
% s is a vector
w=exp(-I*pi^2*Time).*[1,.5*ones(1,length(I)-1)];
wx=w.*(I.^s(1));
wy=w.*(I.^s(2));
out=(-1)^sum(s)*(wy*A2*wx')*pi^(2*sum(s));
end

function out=K(s)
out=(-1)^s*prod((1:2:2*s-1))/sqrt(2*pi);
end

# ----------------------------------------------------------------
My attempt at R translation (not working):
fzero(subtract_evolve, c(0, 0.1))

  K <- function(s) {
    out <- (-1)^s * prod(seq(from = 1,to = 2*s-1, by = 2))/sqrt(2*pi)
    return(out)
 }
  psi <- function(s, time) {
    w <- (exp((-t(I) * pi^2) %*% time)) *  
          t(c(cbind(1, 0.5*ones(1,length(I)-1))))
    wx <- t(w * (I^s[1]))
    wy <- t(w * (I^s[2]))
    out <- (-1)^sum(s) * (wy %*% A2 %*% t(wx)) * pi^(2*sum(s))
    return(out)
  }
  func <- function(s, t) {
    if (sum(s) <= 4) {
      sum_func <- func(c(s[1]+1,s[2]), t) + func(c(s[1],s[2]+1), t)
      const <- (1+1/2^(sum(s)+1))/3
      time <- (-2 * const * K(s[1]) * K(s[2]) / N / sum_func)^(1/(2+sum(s)))
      out <- psi(s, time)
    } else {
      out <- psi(s, t)
    }
    return(out)
  }
  evolve <- function(t) {
    sum_func = func(c(0,2), t) + func(c(2,0), t) + 2*func(c(1,1),t)
    time <- (2*pi*N*Sum_func)^(-1/3)
    out <- (t-time)/time
    return(c(out, time))
  }
  subtract_evolve <- function(t) {
    return(t - evolve(t))
  }

0 个答案:

没有答案