So here's my solution.
If you had problems, it's really no problem.
Maybe you can follow along with me and after each sell that I program, maybe you could stop and think
about how you would continue from there.
So the first thing that I will do, that's not really necessary, but I will do it here is that I will
generate the three data sets.
So for the three oscillators, the first one would be an array.
And then for the X values, we have, the physical T values, which would be solution underscores three
for C T and for the Y values we have solution on to score three or C Dot Y and then zero.
And of course, for the other two datasets we have and the other two indices.
So here one and two.
So this is not a data, and I will show it to you first for data one, which is the oscillator with
the index zero.
So the very left one.
So first of all, we must define, of course, the model function.
So as before we write def function model like in the previous section, but not the previous one, but
one of the earliest sections.
And then we have here the argument, which is T and our case, and we have two parameters which will
be a vector which we call a f and we return a zero times and p dot cosine.
By the way, you could also use sine here.
It doesn't matter because this is just a matter of the faced and we will fit anyway.
So you could write here really cosine.
It doesn't matter.
Of course, I know sine doesn't matter.
So then we multiply by T and we add the factor phase, which will be a one, and then we add the other
two functions so it will copy and then fix it two to three.
Four, three and five.
OK.
Looks good.
No error, so this seems to work, and now we can define the error function, which the courts previously
fit.
And of course, the arguments are to function, which will be our model function.
Then we have the coefficients, which will be eight and we have the data, which will be data one.
So here we had some comments, which I will not write, which explained the parameters, but I think
it's pretty clear.
So we would just go ahead.
And since it's a sum, we will start with the finding this to be zero and then looping for I in range
length data zero.
If you copy this from the previous notebook, then you already have this year and then the error will
be the old error, plus the individual contributions.
And so now we have to, you know, basically program this one here.
So will be the brackets squared and then later I comma one.
So this will be the other way around one comma.
I will be the Y component minus F and then data zero comma I, which will be the X component and then
has the argument for the function DX coefficients.
OK.
And then we print the summer so as not to print the picture.
So as I told you earlier, you don't have to do it the loop.
You can also define an array, of course, and then use to some command.
So this will be our error.
And now I want to just test if everything works.
So I will just use some values for the starting parameters.
I don't know.
We could take random values, but maybe it's good here that we can compare with each other, that I
just take some values.
I don't know.
And then I write error a fit.
Function model, comma a comma data one.
And this will be the era with these, with this value here as a starting value.
So the thing is the arrow should probably be in a similar range for you, but it's probably not exactly
the same value because we have taken random starting conditions for the simulation here.
So your data will look a bit different compared to mine, which is why your number for the error may
be a bit different.
OK, now the next thing will be to define the gradient def arrow gradient or fits gradient we called
it previously.
Then we have here the same arguments.
And once again, it's a song, so I wrote Total equal to zero.
So as I told you previously, you probably copy this just from the other notebook and then you don't
have to write all of what I'm writing right now.
But I think it's better that I just write it one more time so that you can really see what's going on
here in case you do not have the old notebook or you don't want to look it up.
OK?
So we basically have to add up now total the old total plus data one comma I minus half data, zero
comma.
I come out coefficients.
So this is similar thing compared to here.
So this is basically this one.
And then we have to multiply only by this one here.
So this I will call the FDA, which we have to define, of course, the FDA.
And then in the end, we return minus two times total so that we have this factor here.
OK, now we only have to define this one, the FDA, that's an array because it's a vector and you see
what the vector is.
It's just this one.
So now it's a bit annoying.
I just have to tag along and be sine omega one times data as well.
B t so our T list theta zero comma I and then plus a one.
And this we have several times.
But first, let me program this one here.
This will be minus a zero times and p dot sign of this whole thing.
So and p told Sign and now we just have to copy this two more times and then fix, of course, the indices.
All right.
So I copy this.
Here we have our first entries that we had before.
Now, to the other ones, this will be omega two and a three.
Here we have eight to omega to a three.
And finally, Omega three, a five, a four, omega three and a five.
OK, good.
So now this is our gradient so we can call it arrow.
Or maybe just let me copy this that I don't make any typos.
Our fate gradient and then our function model a comma data one.
And so once again, you probably will have different values here because you have a different dataset.
And now I will test what happens if we do one iteration, one step.
So we must defines a learning rate.
So, h, we called it previously, it takes some small value and as I said, I will do one test step.
So a the parameters will be updated according to a change of minus page times.
And then what you just wrote?
So we do this.
And then afterwards, I will print the value of a profit.
So basically this one.
So right now, we have a row of 360, 2.5 four.
Now we have an error of 295 Dot six or five, which is smaller when I rerun it.
It will get smaller and smaller and smaller and smaller until eventually it will turn to zero.
And then the parameters will hopefully look good so that I don't have to type enter over and over.
I write iterations is equal to, I don't know.
Here, of course, it depends sometimes a bit on the starting conditions, how many iterations you need.
Maybe we try out one thousand.
Let's see if it works.
For I in range iterations.
So it could also happen that in your case, you need more or less iterations because you have a different
data.
And also, if you rerun the whole notebook, it could also mean that you need a different number of
iterations.
So it's never bad to have too many iterations, but of course, and it takes much more time.
So we just loop over what we've written here.
OK.
And then finally, we can look at the horrific gradient, and we can also look at the arrow fits, which
can both be zero, approximately.
And then we can have a look at the fit itself.
It's not.
I've run these two cells and for 1000 iterations took for me, maybe like three or four seconds.
And you see, the arrow is now really, really small, close to zero.
Maybe we could iterate a bit more, but hopefully it's OK.
And you can also see the gradient is pretty small.
All of them are below one, except for this one, which is still a bit high.
So maybe 10000 would be better, but let's see what it looks like.
So Peltier here, let me just scroll up to our previous plotting that we copy this, so we need basically
this one.
I would say
it's curled up, and now I will change this year because we have used our data.
We could, of course, leave it as it is, but I think it's nicer to just use data that we actually
used for fitting some data one with the index, zero Theta, one with the index one.
And now we want to plot our Yeah or Fitbit data.
So I real right here t if all this was what we have used for the for the years over.
So I want to show you this so that you believe me here.
When we solved it numerically, we wrote in the integrates dot solve on the score IVP TVL is equal to
this Lind's based function here, so I will copy this go back down to if all is equal to this one.
And now we can plot this Piatti dot plot for T underscore evolved from a function Model T underscore.
You've all.
Common a common threat.
And this one, I will change to a scatterplot.
And you see, this is the solution of the Fit's, which is the rent curve and the blue ones are our
data points that we have used for fighting.
You see, we have used a model function with, which is a superposition of three cosine functions.
And indeed it worked.
It's it's a pretty good fit.
As I said, we could maybe improve it just a little bit more by using more iterations to decrease the
error.
But I think it looks pretty good now and it's a I think it's a remarkable, remarkable fit and really
a nice thing that we have seen when we just take our eigen frequencies, the three Agria frequencies
that we have and we superimpose them, then we can recover the numerical results so we can have a look
at the values of AA, which are the fitted parameters.
And you see you, they are just some, some values.
So this amplitude amplitude and another amplitude, and then we have here the face factors.
So of course, now we can do the exact same thing with the oscillator number two.
And this I will show to you in a second.
So here you can see I have basically copied the code from above.
So basically just starting once again with the first set of parameters and then looping over the gradient
descent where our fit gradient would be this one with now the data set two and then I have plotted everything
once again, and you see, it works very, very well.
And when we look at the parameters, we see that all of them are reasonable values and this one here
is actually very, very small.
So it's much smaller than the other.
So we could assume that it's probably zero.
And when you look at it, what this means is to get the third entry.
And if we go back, what was the third entry?
This was this one.
This was the amplitude for the second function, so the amplitude for the cosine function with omega
two.
And so indeed, this was the omega two frequency here.
And you see, for the second oscillator, this one for the eigenvectors doesn't have an entry for this
particular frequency.
You can also see here in the full transform that the second oscillator does not have a peak here.
So it makes sense that also in the fit, the second cosine function with the Omega two does not is not
taken into account.
And we didn't tell this to the program.
We just said, please find the optimal fit using these three cosine functions.
And it told us that the second cosine function or did we get the best fit if we don't take the second
cosine function into account?
And it's the same result as we got from the you transform and from the eigenvectors.
So basically, we have now another way, or we have found another way that confirms our previous results.
We have first solved the problem numerically.
Then we have solved the eigenvalue problem by calculating the eigenvalues of the matrix that characterizes
the equations of motion.
And from there, we have calculated the EIGEN frequencies, and now we have taken the cosine functions
with the ion frequencies and have superimposed them.
And we just had to fit the parameters a and fine.
And we have seen, OK, it really works.
We can use three harmonic functions to recreate our solution, and everything agrees very, very well.