# Fitting Eigenvalues of a 8*8 matrix to experimental data

I have an 8x8 matrix which contains some parameters with a certain range. I am trying to fit the eigenvalues of this matrix to my experimental data with the goal of

1. having the best fit
2. extracting the best value for the parameters of my matrix

The problem is that Mathematica does not give a well-defined function for the eigenvalues of an 8*8 matrix, so doing a fit is problematic.

In the code below, I tried to plot eigenvalues by choosing a value for parameters, extracting the data points of this plot, and then finding a function for these data points, and then fitting this function to my experimental data. It fits very well but the problem is that I do not extract my main parameters from this fitting.

Do you have any other ideas on how to solve this problem? I would appreciate your help.

This is the matrix:

ParaMatrix = {{Es, 0, Kz*P, 0, 0, -Sqrt[2]*(Kx + I*Ky)*P/2, 0,
Sqrt[2]*(Kx - I*Ky)*P/2}, {0, Ep + δ/3 - Δ/3,
Sqrt[2]*Δ/3, 0, Sqrt[2]*(Kx + I*Ky)*P/2, 0, 0,
0}, {Kz*P, Sqrt[2]*Δ/3, Ep - 2*δ/3, 0, 0, 0,
0, 0}, {0, 0, 0, Ep + δ/3 + Δ/3,
Sqrt[2]*(Kx - I*Ky)*P/2, 0, 0, 0}, {0, Sqrt[2]*(Kx - I*Ky)*P/2, 0,
Sqrt[2]*(Kx + I*Ky)*P/2, Es, 0, Kz*P,
0}, {-Sqrt[2]*(Kx - I*Ky)*P/2, 0, 0, 0, 0,
Ep + δ/3 - Δ/3, Sqrt[2]*Δ/3,
0}, {0, 0, 0, 0, Kz*P, Sqrt[2]*Δ/3,
Ep - 2*δ/3, 0}, {Sqrt[2]*(Kx + I*Ky)*P/2, 0, 0, 0, 0, 0, 0,
Ep + δ/3 + Δ/3}};


Extracting the points:

Points =
Cases[Cases[InputForm[Plotmodel], Line[___],
Infinity], {_?NumericQ, _?NumericQ}, Infinity]


separating a part of the answers:

plot3 =
ListPlot[Points, PlotRange -> {{-0.2, 0.2}, {-1.5, -0.68}},
Joined -> True]

VB3 = Cases[
Cases[InputForm[plot3], Line[___],
Infinity], {_?NumericQ, _?NumericQ}, Infinity]


extracting the formula:

Formula = FindFormula[VB3, y]

Fitting:

nmf = NonlinearModelFit[
data3, -0.7208213695068 -
a*1.7916543143698 Cos[b*y]^11.454237942784 Sin[
27.179143620615 y^2], {a, b, c}, y]

• There are 8 parameters in your model, while in your example 3 only. Could you explain what actually do you try to solve? Commented Jun 25 at 15:45
• What is data3? Commented Jun 25 at 15:57
• @AlexTrounev I think he want Eigenfunctions and eigenvalues Commented Jun 25 at 16:05

You may fit the eigenvalues of an 8x8 parameterized matrix to your experimental data by defining a function that computes the eigenvalues based on given parameter values. Then, define a cost function that measures the difference between these computed eigenvalues and your experimental data, and use an optimization routine to minimize this cost function, thereby extracting the best-fit parameters.

Here is the suggested Mathematica code to achieve this:

(* Define the eigenvalue computation function *)
Clear[EigenvaluesFunction]
EigenvaluesFunction[Es_, Ep_, δ_, Δ_, Kx_, Ky_, Kz_, P_] := Module[
{ParaMatrix},
ParaMatrix = {
{Es, 0, Kz*P, 0, 0, -Sqrt[2]*(Kx + I*Ky)*P/2, 0, Sqrt[2]*(Kx - I*Ky)*P/2},
{0, Ep + δ/3 - Δ/3, Sqrt[2]*Δ/3, 0, Sqrt[2]*(Kx + I*Ky)*P/2, 0, 0, 0},
{Kz*P, Sqrt[2]*Δ/3, Ep - 2*δ/3, 0, 0, 0, 0, 0},
{0, 0, 0, Ep + δ/3 + Δ/3, Sqrt[2]*(Kx - I*Ky)*P/2, 0, 0, 0},
{0, Sqrt[2]*(Kx - I*Ky)*P/2, 0, Sqrt[2]*(Kx + I*Ky)*P/2, Es, 0, Kz*P, 0},
{-Sqrt[2]*(Kx - I*Ky)*P/2, 0, 0, 0, 0, Ep + δ/3 - Δ/3, Sqrt[2]*Δ/3, 0},
{0, 0, 0, 0, Kz*P, Sqrt[2]*Δ/3, Ep - 2*δ/3, 0},
{Sqrt[2]*(Kx + I*Ky)*P/2, 0, 0, 0, 0, 0, 0, Ep + δ/3 + Δ/3}
};
Eigenvalues[ParaMatrix]
]

(* Define the cost function *)
Clear[CostFunction]
CostFunction[params_List, experimentalData_List] := Module[
{computedEigenvalues},
computedEigenvalues = EigenvaluesFunction @@ params;
Total[(computedEigenvalues - experimentalData)^2]
]

(* Example experimental data *)
experimentalData = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8}; (* Replace with actual data *)

(* Initial parameter guesses *)
initialParams = {Es -> 1, Ep -> 1, δ -> 1, Δ -> 1, Kx -> 1, Ky -> 1, Kz -> 1, P -> 1};

(* Perform the optimization *)
bestFit = NMinimize[
CostFunction[{Es, Ep, δ, Δ, Kx, Ky, Kz, P}, experimentalData],
{Es, Ep, δ, Δ, Kx, Ky, Kz, P} /. initialParams
]

(* Extract best-fit parameters *)
bestFitParams = {Es, Ep, δ, Δ, Kx, Ky, Kz, P} /. bestFit[[2]]

(* Compute eigenvalues using best-fit parameters *)
bestFitEigenvalues = EigenvaluesFunction @@ bestFitParams

(* Compare with experimental data *)
{bestFitEigenvalues, experimentalData}


• One drawback to this, and to my response as well, is that both can be thwarted by how the eigenvalues get sorted. (Possibly there’s a limerick lurking in that.) Commented Jun 26 at 6:08
• Hi, Thanks for your answer. I received an error due to not having a WeLL DEFINED FUNCTION FOR EIGEN values. NMinimize::ivar: 0.53 is not a valid variable. Commented Jun 26 at 10:03
• You likely had one of the matrix symbolic parameters set to a value. That's the usual cause for this type of error message. Commented Jun 26 at 15:40

Here is an artificial example, where we have a given set of eigenvalues and want to fit the matrix parameters to obtain eigenvalues as close to the set as possible.

ParaMatrix = {{Es, 0, Kz*P, 0, 0, -Sqrt[2]*(Kx + I*Ky)*P/2, 0,
Sqrt[2]*(Kx - I*Ky)*P/2}, {0, Ep + \[Delta]/3 - \[CapitalDelta]/3,
Sqrt[2]*\[CapitalDelta]/3, 0, Sqrt[2]*(Kx + I*Ky)*P/2, 0, 0,
0}, {Kz*P, Sqrt[2]*\[CapitalDelta]/3, Ep - 2*\[Delta]/3, 0, 0, 0,
0, 0}, {0, 0, 0, Ep + \[Delta]/3 + \[CapitalDelta]/3,
Sqrt[2]*(Kx - I*Ky)*P/2, 0, 0, 0}, {0, Sqrt[2]*(Kx - I*Ky)*P/2, 0,
Sqrt[2]*(Kx + I*Ky)*P/2, Es, 0, Kz*P,
0}, {-Sqrt[2]*(Kx - I*Ky)*P/2, 0, 0, 0, 0,
Ep + \[Delta]/3 - \[CapitalDelta]/3, Sqrt[2]*\[CapitalDelta]/3,
0}, {0, 0, 0, 0, Kz*P, Sqrt[2]*\[CapitalDelta]/3,
Ep - 2*\[Delta]/3, 0}, {Sqrt[2]*(Kx + I*Ky)*P/2, 0, 0, 0, 0, 0, 0,
Ep + \[Delta]/3 + \[CapitalDelta]/3}};

vars = Variables[ParaMatrix];


Create a set of (real) eigenvalues, ordered by values.

SeedRandom[1234];
data = Sort@RandomReal[{-10, 10}, Length[ParaMatrix]]

(* Out[189]= {-9.76711, -8.27553, -2.44174, -0.413367, 0.439285,
0.875135, 7.53217, 8.54532} *)


We will minimize an objective function defined only when the matrix parameters are given actual values.

normdiffs[vals : {_?NumericQ ..}] :=
With[{diffs =
Sort@Eigenvalues[ParaMatrix /. Thread[vars -> vals]] - data},
diffs . diffs]

{res, vals} = NMinimize[normdiffs[vars], vars]

(* Out[200]= {3.77777, {Ep -> -0.361877, Es -> -0.667285, Kx -> 1.08509,
Ky -> 0.958071, Kz -> -0.809323,
P -> -5.06014, \[Delta] -> 0.0333604, \[CapitalDelta] -> -3.19205}} *)


We use a simple eigenvalue computation to check this. The result is so-so. maybe that's the best one can do with this set of values though.

numericEigvals[vals : {_?NumericQ ..}] :=
`