Ошибка «сингулярный градиент» или «коэффициент шага ниже minFactor» при попытке подгонки модели nls к данным - PullRequest
3 голосов
/ 14 апреля 2019

Мы измерили частоту, двойную амплитуду входного и выходного сигнала и разницу во времени между входным и выходным сигналом для фильтра нижних частот с резистором 10 кОм и конденсатором 10 нФ в лаборатории.Оттуда мы вычислили разность фаз.
Теперь я рассчитал экспериментальное значение для функции передачи напряжения (G.exp) и хочу подогнать нелинейную модель через мою точку данных, чтобы оптимизировать мои параметры.
Все работаетхорошо, пока я не вызову функцию:

fit <- nls(G.exp ~ a*Vierpol(w.exp, C), 
    trace=TRUE, start=list(a=1, C=100e-9))

Сначала я попытался увеличить minFactor для решения step factor below 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, как я могу определить диапазон ошибок?
В любом случае, я 'm снова:

Ошибка в nls (Gexp ~ a * Vierpol (wexp, C) + runif (7, 8, 9), trace = TRUE,: Schrittweitenfaktor 0.000488281 unter 'minFactor' 0.000976562 reduziertКроме того: было 50 или более предупреждений (используйте предупреждения (), чтобы увидеть первые 50)

Image of model

...