2
$\begingroup$

I have the following problem that I can't figure out how to solve. I have two measured signals, (data1 and data1), and their measured sum (datasummeasured). I have a theoretical description of how the two signals should be summed, but the equation has one free parameter that I need to determine by matching the measured summ with the calculated summ from the two measured single signals.

I can't use any of the regular fitting routines, because the equation I have is not used to describe the function shape of the data, but how two separate sets of data can be summed up to generate a third. In the example below I would like to fit the calculated sum data to the measured sum data by changing the parameter called "orthogonality".

SignalSum[S1_ , S2_, Ortogonality_] := 
  N[Sqrt[(S1 ^2 + S2 ^2) + 2 S1 S2 Cos[Ortogonality]]];
data1 = {{1., 0.63}, {0.5, 0.85}, {0., 1.02}, {-0.5, 0.97}, {-1., 0.87}, {-1.5, 0.77}, {-2., 0.75}, {-2.5, 0.72}, {-3., 0.66}, {-3.5, 0.48}, {-4., 0.36}};
data2 = {{1., 0.61}, {0.5, 0.79}, {0., 1.02}, {-0.5, 1.09}, {-1., 1.07}, {-1.5, 0.93}, {-2., 0.77}, {-2.5, 0.63}, {-3., 0.47}, {-3.5, 0.38}, {-4., 0.27}};

datasummeasured = {{1., 0.72}, {0.5, 0.93}, {0., 1.15}, {-0.5, 1.17}, {-1., 1.15}, {-1.5, 1.02}, {-2., 0.9}, {-2.5, 0.83}, {-3., 0.74}, {-3.5, 0.56}, {-4., 0.41}};


ortogonality = 1.5; (*I would like to make this parameter variable and obtain it by matching the measured sum data with the calculated sum data*)
signalsumm = 
  Table[{data1[[i, 1]], 
    SignalSum[data1[[i, 2]], data2[[i, 2]], ortogonality]}, {i, 1, 
    Length[data1]}];

ListPlot[{data1, data2, datasummeasured}, PlotRange -> All, 
 Joined -> False, 
 PlotLegends -> {"Singal 1", "Singal 2", "Measured summ"}, 
 Frame -> True,  PlotLabel -> "Measured signals"]

ListPlot[{datasummeasured, signalsumm}, PlotRange -> All, 
 Joined -> False, PlotLegends -> {"Measured summ", "Calculated Sum"}, 
 Frame -> True,  PlotLabel -> "Measured vs. Calculated sum"] 


````
$\endgroup$

1 Answer 1

2
$\begingroup$

For convenience, let's redefine your summing function so it takes the two lists at once, rather than point-wise:

ClearAll[signalSum2]
signalSum2[S1_List, S2_List, Ortogonality_] :=
   Sqrt[(S1[[All, 2]]^2 + S2[[All, 2]]^2) + 2 S1[[All, 2]] S2[[All, 2]] Cos[Ortogonality]]

Let's then construct a sum of square deviations between the calculated sum (as a function of orthogonality) and the measured one, and minimize that sum of squares to obtain the optimal value of the orthogonality parameter:

sumOfSquares = Total@(datasummeasured[[All, 2]] - signalSum2[data1, data2, orth])^2;
bestfit = NMinimize[{sumOfSquares, 0 <= orth <= 2 Pi}, orth]

(* Out: {2.3202*^-24, {orth -> 4.4061}}*)

Let's plot the results and compare them to the measured values:

ListPlot[
  {
    datasummeasured,
    Transpose[{datasummeasured[[All, 1]], signalSum2[data1, data2, orth /. Last@bestfit]}]
  },
  PlotStyle -> {Black, Directive[PointSize[0.02], Opacity[0.5, Red]]},
  PlotLegends -> {"measured", "calculated"}
]

good fit between experimental and calculated

Note that there are multiple similar minima for the orthogonality parameter; for instance, the results are not much different for $\text{orthogonality} = 1.87$. I have constrained the value of the parameter to $[0,2\pi]$ because it is the argument of a cosine and therefore periodic, but perhaps you could constrain it further from insight into your physical system.

$\endgroup$
1
  • $\begingroup$ Thank you @MarcoB! I was not aware that you could define functions to go over specific parts of a list :) it is a great trick $\endgroup$
    – Niky177
    Commented Jul 21, 2023 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.