简体   繁体   English

R-使用全局变量来求解ode45,类似于MATLAB / GNU Octave

[英]R - use global variables to solve ode45 similar to MATLAB/GNU Octave

I am attempting to rewrite code from GNU Octave/MATLAB in R version 3.3.1. 我正在尝试从R版本3.3.1中的GNU Octave / MATLAB重写代码。 In the original code, A and B were set as global variables in a function and then in the script file both A and B were set as global variables. 在原始代码中,将A和B设置为函数中的全局变量,然后在脚本文件中将A和B均设置为全局变量。

In R, this is the error message that I receive when I attempt to use the ode45 function: 在R中,这是我尝试使用ode45函数时收到的错误消息:

Error in eval(expr, envir, enclos) : object 'z1' not found eval(expr,envir,enclos)中的错误:找不到对象“ z1”

Can anyone suggest how to set the global variables in R as was done in the GNU Octave/MATLAB code? 谁能像在GNU Octave / MATLAB代码中一样建议如何在R中设置全局变量?

Thank you. 谢谢。


R code follows R代码如下

#list.R is a wrapper for list used to replicate the GNU Octave/MATLAB syntax


source("https://raw.githubusercontent.com/ggrothendieck/gsubfn/master/R/list.R")

install.load::load_package("ramify", "pracma")

GRT <- function (t, x) {
         A  <- A
         B  <- B
         z1 <- x[1, 1]; z2 <- x[2, 1]; z3 <- x[3, 1]; X <- mat("z1; z2; z3")
         xd <- A * X + B * exp(-t) * sin(400 * t)
}


A <- -mat("2, 3, 2; 1, 5, 3; 2, 3, 1")
B <- mat("1; 3; 2")

ts <- 0.0
tf <- 10
X0 <- c(1, 0, -1)

list[t, x] <- ode45(GRT, ts, tf, X0)

P <- mat("t, x")

matplot(t, x, xlab = "time - (s)", ylab = "x")

I am using GNU Octave, version 3.8.1 to run the code. 我正在使用GNU Octave版本3.8.1来运行代码。 The following code in GNU Octave/MATLAB is what I have attempted to replicate above: 我在上面试图复制的是GNU Octave / MATLAB中的以下代码:

function xd=GRT(t,x)
global A B
z1=x(1,1); z2=x(2,1);z3=x(3,1);X=[z1;z2;z3];
xd =A*X+B*exp(-t)*sin(400*t);
endfunction % only needed for GNU Octave

global A B
A = -[2,3,2;1,5,3;2,3,1];
B = [1;3;2];
ts = 0.0;
tf = 10;
T=[ts,tf]; X0=[1,0,-1];
[t,x] = ode45(@GRT,T,X0)
P = [t,x];
plot(t,x)
xlabel('time - (s)');
ylabel('x');

This is X : 这是X

X =

1.0000
1.0016
1.0043

The size of t is 809 rows, 1 column. t的大小是809行1列。 This is a partial look at t . 这是t的局部t

t =

0.00000
0.00305
0.00632
0.00928
0.01226
0.01524
0.01840
0.02186
0.02482
0.02778
0.03079
0.03391
0.03750
0.04046
0.04344
0.04646
0.04959
0.05321
0.05618

The size of x is 809 rows, 3 columns. x的大小为809行3列。 This is a partial look at x . 这是x的局部x

x =

1.0000e+00   0.0000e+00  -1.0000e+00
1.0016e+00   1.0937e-02  -9.9982e-01
1.0043e+00   2.5810e-02  -9.9752e-01
1.0040e+00   3.1460e-02  -1.0007e+00
1.0012e+00   2.9337e-02  -1.0090e+00
9.9908e-01   2.9132e-02  -1.0161e+00
1.0001e+00   3.8823e-02  -1.0170e+00
1.0028e+00   5.4307e-02  -1.0148e+00
1.0026e+00   6.0219e-02  -1.0178e+00
9.9979e-01   5.8198e-02  -1.0260e+00
9.9739e-01   5.7425e-02  -1.0336e+00
9.9809e-01   6.6159e-02  -1.0351e+00
1.0007e+00   8.1786e-02  -1.0331e+00
1.0004e+00   8.7669e-02  -1.0361e+00
9.9753e-01   8.5608e-02  -1.0444e+00
9.9500e-01   8.4599e-02  -1.0522e+00

This is the expected plot: 这是预期的情节:

GRT图

I believe this is what you wanted: 我相信这就是您想要的:

source("https://raw.githubusercontent.com/ggrothendieck/gsubfn/master/R/list.R")

pacman::p_load(ramify, pracma) # I use pacman, you don't have to

GRT <- function (t, x) {
  X <- mat("z1; z2; z3")
  xd <- A %*% X + B %*% exp(-t) * sin(400 * t)
  return(z1)
}


A <- -mat("2, 3, 2; 1, 5, 3; 2, 3, 1")
B <- mat("1; 3; 2")

ts <- 0.0
tf <- 10
X0 <- c(1, 0, -1)
z1 <- X0[1]
z2 <- X0[2]
z3 <- X0[3] 

GRT(t=ts,x=X0)

list[t, x] <- ode45(GRT, ts, tf, X0)

P <- mat("t, x")

matplot(t, x, xlab = "time - (s)", ylab = "x")

Changes made: 所做的更改:

  1. Used matrix multiplication operator in GRT instead of scalar multiplication GRT使用矩阵乘法运算符代替标量乘法
  2. Fixed the indexing of X0 (called x in your function) 修复了X0的索引(在函数中称为x
  3. Commented out 2 unnecessary lines from GRT 注释掉了GRT 2条不必要的内容
  4. Added a return statement to GRT GRT添加了return语句

I had to make some assumptions about what you were trying to do where the syntax was wrong, like with the indexing of X0 . 我必须对语法错误的地方做些假设,例如对X0进行索引。 Since I didn't have the example output plot from Octave to reference (and I can't get your code to run in my Octave CLI) I can't tell if those assumptions were correct, and if not my plot may be different. 由于我没有从Octave到参考的示例输出曲线图(而且我无法让您的代码在Octave CLI中运行),因此我无法确定这些假设是否正确,如果不是,我的曲线图可能会有所不同。

This is the resulting plot from the code above: 这是上面代码的结果图:

在此处输入图片说明

Final note: It looks like you never used the result of P <- mat("t, x") anyway, but I don't think it does what you think it's doing anyway, based on the resulting object. 最后的注意:看来您从未使用过P <- mat("t, x")的结果,但是我不认为它会根据结果对象来做您认为正在做的事情。

The following answer uses some elements from the various comments and the answer by Hack-R. 以下答案使用了各种注释中的一些元素以及Hack-R的答案。

source("https://raw.githubusercontent.com/ggrothendieck/gsubfn/master/R/list.R")

install.load::load_package("ramify", "pracma")

GRT <- function (t, x) {

z1 <- x[1, 1]; z2 <- x[2, 1]; z3 <- x[3, 1]; X <- matrix(data = c(z1,  
z2, z3), nrow = 3, ncol = 1)

xd <- A %*% X + B * exp(-t) * sin(400 * t)

return(xd)
}


A <- -mat("2, 3, 2; 1, 5, 3; 2, 3, 1")

B <- mat("1; 3; 2")

ts <- 0.0

tf <- 10

X0 <- c(1, 0, -1)

list[t, x] <- ode45(GRT, ts, tf, X0, atol = 0.000001, hmax = 1.0)

matplot(t, x, xlab = "time - (s)", ylab = "x", type = "l")

R中的ode45图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM