在实验室中,我们测量了具有10 kOhm电阻和10nF电容器的低通滤波器的频率,输入和输出信号的两倍振幅以及输入和输出信号之间的时间差。从那里我们计算出相位差。
我现在计算了电压传递函数(G.exp)的实验值,并希望通过我的数据点拟合非线性模型,以优化我的参数。
一切正常,直到我调用函数:
fit <- nls(G.exp ~ a*Vierpol(w.exp, C),
trace=TRUE, start=list(a=1, C=100e-9))
首先,我尝试通过设置step factor below minFactor
来增加minFactor以解决control=nls.control(minFactor=1/8192)
的问题,但这导致步长和minFactor减小。
然后,我尝试更改a和C的起始值,这导致出现错误消息singular gradient
#ELK - Lowpass Filter
rm(list=ls())
setwd("C:/working/dir/ELK")
######################### Values
#Read frequency, Double Amplitude from incoming signal and outcoming signal, measured time difference and calculated phase
#from a constructed lowpass filter with 10k Ohm resistor and 10 nF capacitor
#from a csv file
freq <- read.csv("Filters.csv", sep= ";", skip = 0)[,c(1)]#frequency in kHz
AmpUa <- read.csv("Filters.csv", sep= ";", skip = 0)[,c(3)] #2*Amplitude in Volt
AmpUe <- read.csv("Filters.csv", sep= ";", skip = 0)[,c(2)] #2*Amplitude in Volt
phase <- read.csv("Filters.csv", sep= ";", skip = 0)[,c(5)] #Phase (without unit)
time <- read.csv("Filters.csv", sep= ";", skip = 0)[,c(4)] #Time difference of signals in ms
Log <- function(begin=1e-10, end=1e10) {
d <- 10^c(-99:99)
d <- d[d>=begin & d<=end]
dd <- outer(c(1:9), 10^c(-99:99))
dd <- dd[dd>=begin & dd<=end]
dlab <- do.call("expression",
lapply(seq(along=log10(d)),function(i) substitute(10^E,list(E=log10(d)[i]))))
list("big"=d, "small"=dd, "big.lab"=dlab)
}
lg <- Log()
######################### Amplitude
#function Vierpol gives back the theoretical value of the Voltage transfer function
Vierpol <- function(w, C) { # Lowpass
ZC <- (0+1i)/(-w*C)
ZR <- 10000
Ztot <- ZR+ZC
Gk <- ZR/Ztot
abs(Gk)
}
f <- freq * 1000 #transfer frequency from KHz to Hz
C <- 10e-9 #capacitor in Faraday
fg <- 1591 #Border frequence of the filter (calculated value)
x <- f/fg #ratio btw fg and data (wwg)
ch1 <- AmpUe/2 #measured Amplitude
ch2 <- AmpUa/2 #measured
wexp <- 2*pi*f #experimental angular frequency
Gexp <- ch2/ch1 #experimental value of the voltage transfer function
plot(f, Gexp, las=1, log = "x", xlim=c(10, 1e6), ylim=c(0, 1.1), xlab=expression(italic(f) ~ " [Hz]"), ylab=expression("|G("~italic(f)~")|"), axes=FALSE)
# fit to Gexp = a * Vierpol(wexp, R ,C)
#try to fit the experimental point through a non linear model and optimize the parameters a and C
fit<- nls(Gexp ~ a * Vierpol(wexp, C),
trace=TRUE, start=list(a=1, C=10e-9))
axis(1, at = lg$big, labels = lg$big.lab)
axis(1, at = lg$small, labels = FALSE, tcl = -0.25)
axis(2)
box()
#print(summary(fit))
fc <- 10^seq(1, 6, 0.01) # get the range 10Hz-> 1MHz
Gc <- predict(fit, list(wexp = 2*pi*fc)) # fit function for x
lines(fc, Gc) # draw the line
points(f, Gexp, pch=21, bg="white")
我已经可以绘制实验数据点,但是无法通过这些数据点拟合任何模型。
如何通过实验点拟合nls模型?
错误消息以供参考:
fit<- nls(Gexp ~ a * Vierpol(wexp, 500, C),
+ trace=TRUE, start=list(a=1, C=10e-9), control=nls.control(minFactor=1/1024))
16.19366 : 1e+00 1e-08
7.865624 : -1.105361e-01 2.118218e-08
7.694877 : -1.051039e-01 -1.234647e-08
7.564449 : -1.046308e-01 5.939512e-09
7.511479 : -1.034139e-01 -4.054490e-09
7.500272 : -8.842691e-02 5.026213e-09
7.459853 : -8.841959e-02 -3.283024e-09
7.447777 : -7.526479e-02 3.808724e-09
7.399803 : -7.384654e-02 -1.698359e-09
7.351996 : -7.276184e-02 1.177592e-10
7.350372 : -1.259269e-01 2.873937e-11
Error in nls(Gexp ~ a * Vierpol(wexp, 500, C), trace = TRUE, start = list(a = 1, : step factor reduced 0.000488281 below 'minFactor' 0.000976562
fit<- nls(Gexp ~ a * Vierpol(wexp, C),
+ trace=TRUE, start=list(a=9.570e-01, C=1.948e-07))
15.52989 : 9.570e-01 1.948e-07
4.054572 : 2.187341e-01 8.618412e-06
Error in nls(Gexp ~ a * Vierpol(wexp, C), trace = TRUE, start = list(a = 0.957, : singulärer Gradient
编辑:
我添加了我的模型的图像。我不明白添加runif
来扩大错误范围有什么帮助。
fit<- nls(Gexp ~ a * Vierpol(wexp, C) + runif(Some_val),
trace=TRUE, start=list(a=1, C=10e-9))
我为Some_val
尝试了不同的值,如何确定错误范围?
无论如何,我又得到了:
nls(Gexp〜a * Vierpol(wexp,C)+ runif(7,8,9)中的错误,trace = 是的,:Schrittweitenfaktor 0.000488281 unter'minFactor' 0.000976562 reduziert另外:有50个或更多警告(使用warnings()查看前50个)