Search code examples
rdata-fittingnls

Method to calculate complex residuals between a complex function and data containing real and imaginary parts


I am working on building a script in RStudio which can fit Complex Impedance data of the form Z = a + ib, to model formulas which aim to describe how Z changes with frequency. I have seen for other languages that a good route to go about this is by minimising the residuals between the complex values predicted and the complex values recorded as data. I am a little confused about how to actually implement this in R. Is there are a general route to do this in R?

Apologies for not providing more example code - I have encoded the functions and loaded my data but past this I am not really sure what to do.

A typical function is of the form:

ZRC <- function(R2, C1)((R2)/(1+1*i*R2*w*C1))

Where w is recorded from the data. I tried forming a function which is the difference between this and the data Z and then minimising this using nls():

diff <- function(R1, R2, C1)(Z - (R2)/(1+1*i*R2*w*C1))

model1 <- nls(diff~0, start = list(R1 = 10, R2 = 100, C1 = 1E-6))

But this gave an error message saying object is not a matrix


Solution

  • Not tested, but you will probably be best off writing a function that computes the sum of the moduli (or the sum of squares of the moduli) and passing that to optim() to minimize, something like:

    ## Z, w are global variables in this example
    sum_mod_fun <- function(p) {
        ## parameters must be specified as a vector; unpack them
        R1 <- p[1]; R2 <- p[2]; C1 <- p[3]
        pred <- R1 + R2/(1+(1i*R2*w*C1))  ## check formula!
        return(sum(Mod(pred-Z)^2))
    }
    optim(fn = sum_mod_fun, 
          par = c(R1 = 10, R2 = 10, C1 = 0.00001))
    ## note, in this example parameter vector must be in the right order - not checked!