DiffEqFlux.jl
DiffEqFlux.jl copied to clipboard
SingularException using collocate_data
Hi folks,
I've been trying to use the two-stage training method for collocation (as described in this example https://diffeqflux.sciml.ai/stable/examples/collocation/). I can run the example itself and it works great, but when I apply it to my own ODE I get this:
du,u = DiffEqFlux.collocate_data(data,tsteps)
SingularException(2)
in eval at base\boot.jl:360
in top-level scope at nn_training.jl:218
in collocate_data at DiffEqFlux\GQl0U\src\collocation.jl:132
in collocate_data at DiffEqFlux\GQl0U\src\collocation.jl:142
in map at base\abstractarray.jl:2294
in collect_similar at base\array.jl:606
in _collect at base\array.jl:691
in iterate at base\generator.jl:47
in at DiffEqFlux\GQl0U\src\collocation.jl:149
in \ at stdlib\v1.6\LinearAlgebra\src\generic.jl:1128
in \ at stdlib\v1.6\LinearAlgebra\src\diagonal.jl:631
in ldiv! at stdlib\v1.6\LinearAlgebra\src\diagonal.jl:624
In trying to figure out whether it was some artifact of my data that was causing the problem, I found the same thing happening even with simple functions:
t = LinRange(0.0, 30.0, 100)
u = sin.(t)
du,u = DiffEqFlux.collocate_data(u',t)
# Same error
What's even more perplexing is that changing the timespan makes a difference:
t = LinRange(0.0, 15.0, 100)
u = sin.(t)
du,u = DiffEqFlux.collocate_data(u',t)
# SingularException(3) this time
t = LinRange(0.0, 18.0, 100)
u = sin.(t)
du,u = DiffEqFlux.collocate_data(u',t)
# Works
Kernel choice and presence/absence of noise don't seem to matter. I'm afraid I'm not familiar with the details of how the collocation method works, so I have no idea why the system would need to solve a singular matrix. Could someone enlighten me as to why this happens and how I can get this method to work consistently?
It might require u to be a matrix?
Still doesn't work, but for other reasons:
t = Array(LinRange(0.0, 18.0, 100))
t = reshape(t, 1,100)
x = sin.(t)
du,u = DiffEqFlux.collocate_data(x,t)
# ArgumentError: number of rows of each array must match (got (100, 1))
Taking the transpose of x makes no difference.
Edit: Tried again with a column vector instead of a row vector.
t = Array(LinRange(0.0, 18.0, 100))
t = reshape(t, 100,1)
x = sin.(t)
du,u = DiffEqFlux.collocate_data(x,t)
This time it gives SingularException(1)
Hey! Did you manage to get this right? I'm facing the same problem. Always throwing singular expection even with large noise.
Yes, I am still getting the error even on the latest version of DiffEqFlux.
I figured out how to solve it for my case. It turns out that inserting data with too distinct scales and with slow dynamics causes exception. In my case, "t" (independent variable) was between 0 and 3000 and y (dependent) between 0 and 0.5. It caused the derivatives to be too small as delta_t is too large compared to delta_y. I first divided t by 3000 and used the collocate_data(), then divided the calculated derivative by 3000 (to have the correct order of magnitude back).
Yes I think that is probably the right way to go.
The re-scaling is done on the latest versions.