# Multivariate Nonlinear Regression

**URL:** https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887
**Category:** Optimization (Mathematical)
**Created:** [July 1, 2019, 7:13am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887 "2019-07-01T07:13:58Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)
#### Post date: [July 1, 2019, 7:13am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/1 "2019-07-01T07:13:58Z")

</div>

Greetings!

I am trying to perform a multivariate nonlinear regression (2D curve fitting). Let’s assume my data has the following form:

```julia
function multimodel(x, p)
    a = x[1]
    t = x[2]
    α = p[1]
    τ = p[2]
    (α .* a) * (τ .* (t.^2)')
end

t = -1.0:0.1:1.0 |> collect
a = 0.0:0.1:1.0 |> collect
p = [0.9,1.1]
x = [a, t]

y = multimodel(x, p) + 0.1 * rand(length(a), length(t))

using PyPlot
mesh(t, a, y)

```

Which gives the following noisy data:  
 ![download-17](https://global.discourse-cdn.com/julialang/original/3X/f/4/f4eabebb2fe9f5af796e82220cde514daecc0a4b.png)

I tried fitting using `LsqFit`:

```julia
using LsqFit
fit = curve_fit(multimodel, x, y, [1.0, 1.0])

```

which results in

```plaintext
MethodError: no method matching isinf(::Array{Float64,1})

```

I have to admit that that’s not how the `LsqFit` documentation says how their multivariate regression works. In there it states:

> There’s nothing inherently different if there are more than one variable entering the problem. We just need to specify the columns appropriately in our model specification:  
> `@. multimodel(x, p) = p[1]*exp(-x[:, 1]*p[2]+x[:, 2]*p[3])`

But I don’t quite understand that because the arrays of the two independent variables must have the same length? And I don’t get a 2D array out of that function.

I also tried modelling my problem with `JuMP` but I didn’t get very far there.

Does anyone have some experience with this kind of curve fitting?

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [July 1, 2019, 8:19am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/2 "2019-07-01T08:19:06Z")

</div>

I’m not sure what you’re doing exactly.

Do you want to do non-linear least squares, or do you want to interpolate?

---

<div class="post-metadata">

### Author: ![slowbrain](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/slowbrain/32/2224_2.png) [@slowbrain](https://discourse.julialang.org/u/slowbrain)
#### Post date: [July 1, 2019, 8:58am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/3 "2019-07-01T08:58:40Z")

</div>

it seems that wrong argument is passed to `isinf` by `curve_fit` somewhere along the way  
try to overload `isinf` to cover `isinf(::Array{Float64,1})` case and see it you get something reasonable out of the fit

---

<div class="post-metadata">

### Author: ![slowbrain](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/slowbrain/32/2224_2.png) [@slowbrain](https://discourse.julialang.org/u/slowbrain)
#### Post date: [July 1, 2019, 9:12am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/4 "2019-07-01T09:12:14Z")

</div>

disregard my suggestion, no use… I’ve tried to overload `isinf` and `isnan` but ended up with `ERROR: StackOverflowError:` with no details

---

<div class="post-metadata">

### Author: ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)
#### Post date: [July 1, 2019, 9:23am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/5 "2019-07-01T09:23:18Z")

</div>

The plan is to do nonlinear least squares fitting.

---

<div class="post-metadata">

### Author: ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)
#### Post date: [July 1, 2019, 9:26am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/6 "2019-07-01T09:26:03Z")

</div>

In the readme of LsqFit they pass a 2d array as x. I think you passed an array of arrays.

@. multimodel(x, p) = p[1]\*exp(-x[:, 1]\*p[2]+x[:, 2]\*p[3])

---

<div class="post-metadata">

### Author: ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)
#### Post date: [July 1, 2019, 10:19am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/7 "2019-07-01T10:19:34Z")

</div>

> [@feanor12](#):
>
> In the readme of LsqFit they pass a 2d array as x. I think you passed an array of arrays.
> 
> @. multimodel(x, p) = p[1]\*exp(-x[:, 1]\*p[2]+x[:, 2]\*p[3])

This is where I don’t get the readme. If I pass a 2D array the first thing is that my independent variable arrays have to have the same length which they don’t have. And secondly that the `multimodel` function from the readme returns a 1D array instead of a 2D array.

---

<div class="post-metadata">

### Author: ![feanor12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feanor12/32/8212_2.png) [@feanor12](https://discourse.julialang.org/u/feanor12)
#### Post date: [July 1, 2019, 11:46am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/8 "2019-07-01T11:46:56Z")

</div>

maybe try something like this

```julia
function multimodel(x, p)
    a = x[:,1]
    t = x[:,2]
    α = p[1]
    τ = p[2]
    @. α * a * τ * t^2
end

a = []
t = []
trange = -1.0:0.1:1.0
arange = 0.0:0.1:1.0
for _t in trange , _a in arange
    push!(a,_a)
    push!(t,_t)
end

p = [0.9,1.1]
x = [a t]

y = multimodel(x, p) + 0.1 * rand(size(a,1))

using Plots
Plots.plot(a,t,y,seriestype=:surface)

```

---

<div class="post-metadata">

### Author: ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)
#### Post date: [July 1, 2019, 11:56am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/9 "2019-07-01T11:56:58Z")

</div>

> [@feanor12](#):
>
> maybe try something like this  
> […]

Yes! This works! That really helps a lot. Thank you! 🤩

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [July 2, 2019, 11:44am UTC](https://discourse.julialang.org/t/multivariate-nonlinear-regression/25887/10 "2019-07-02T11:44:01Z")

</div>

Okay, now I see what you wanted to do. Do you realize why the suggestion worked?

To use LsqFit you need to provide a number (N) of _observations_. In your case, the observations are chosen by you: you want to sample a the full tensor grid defined by two (in this case) vectors. Then you have to consider each combination/point as one observation. This obviously means that some `a`s are going to be repeated for some `t`s and vice versa. This is the part I didn’t understand when you said “why do a and t have to be of the same length” - well because you need N pairs!
