Work with complex number in function

Hello everyone,

I haven’t solved my problem with complex number in function yet. Problem: I need a " | BW1 + rho * Exp(i phi) * BW2 |^2 " TF1 function. In code I expect to see something this:
TF1* core = new TF1("core"," TMath::Power( TMath::Abs( [0]*TMath::BreitWigner(x, [1], [2]) + [3] * TMath::Exp(i * [4]) * TMath::BreitWigner(x, [5], [6]) ), 2)", inf, sup);

But I don’t understand how make i in TMath::Exp(i * [4])! I looked TComplex class but didn’t understand how use them.


Please read tips for efficient and successful posting and posting code

ROOT Version: 6.22/08
Platform: Ubuntu
Compiler: Not Provided


Try:

TF1 *core = new TF1("core", "TMath::Sq(TComplex::Abs([0] * TMath::BreitWigner(x, [1], [2]) + [3] * TComplex::Exp(TComplex(0., [4])) * TMath::BreitWigner(x, [5], [6])))", 0., 1.);

and / or:

#include "TMath.h"
#include "TF1.h"

#if 1 /* 0 or 1 */

#include <complex>
double core_cpp(const double *x, const double *p)
{return std::norm(p[0] * TMath::BreitWigner(x[0], p[1], p[2]) + p[3] * std::exp(std::complex<double>(0., p[4])) * TMath::BreitWigner(x[0], p[5], p[6]));}

#else /* 0 or 1 */

#include "TComplex.h"
double core_cpp(const double *x, const double *p)
{return TMath::Sq(TComplex::Abs(p[0] * TMath::BreitWigner(x[0], p[1], p[2]) + p[3] * TComplex::Exp(TComplex(0., p[4])) * TMath::BreitWigner(x[0], p[5], p[6])));}

#endif /* 0 or 1 */

TF1 *core = new TF1("core", core_cpp, 0., 1., 7); // 7 parameters

@Wile_E_Coyote , thank you, it run. But later I need to do convolution with normal distributio. I try do this with CONV:
CONV(TMath::Sq(TComplex::Abs([0] * TMath::BreitWigner(x, [1], [2]) + [3] * TComplex::Exp(TComplex(0., [4])) * TMath::BreitWigner(x, [5], [6]))), TMath::Exp(-0.5*((x-[0])/[1]*(x-[0])/[1]))/(sqrt(2*TMath::Pi())*[1]))

This don’t work correct and I get:
Warning in <TCanvas::ResizePad>: Inf/NaN propagated to the pad. Check drawn objects. Warning in <TCanvas::ResizePad>: Pi0-Rho height changed from 0 to 10

There are too many variables, so the CONV can’t cope and you need to think about other ways of convolution?

Hi,

Are you not making life complicated complicated invoking complex numbers? Your function is f=f1+e^iaf2 and you want to fit sqrt(ff) which is sqrt(f1^2×f2^2+2f1f2cos^2a)… Maybe this is easier to feed to a convoluted?

Cheers

Joa

Hi,

you have made a little mistake: f1^2 + f2^2 + 2 f1 f2 cos^2 (a), not f1^2 * f2^2 + 2 f1 f2 cos^2 (a). But I got the idea. I think I want to have the most general form of the formula to easily change or add participating functions. If I use the consequence formula, then with each replacement it will have to be deduced anew. And if I write the initial one and then the algorithm for its transformation, then I don’t have to calculate anything, the machine will do it.

f1^2 + f2^2 + 2 f1 f2 cos(a)

{
  TF1 *core = new TF1("core",
    "TMath::Sq(TComplex::Abs([0] * TMath::BreitWigner(x, [1], [2]) + [3] * TComplex::Exp(TComplex(0., [4])) * TMath::BreitWigner(x, [5], [6])))",
    0., 1.);
  // core->Print();
  TF1 *ngaus = new TF1("ngaus", "TMath::Gaus(x, [0], [1], 1)", 0., 1.);
  // ngaus->Print();
  TF1 *conv = new TF1("conv", "CONV(core, ngaus)", 0., 1.);
  // conv->Print();
  // gROOT->GetListOfFunctions()->ls();
  conv->SetLineColor(kGreen);
  conv->SetNpx(1000);
  conv->SetRange(-50., 50.);
  conv->SetParameters(
    1.,
    -2.5, 5., // BreitWigner
    1.,
    0., // e.g., TMath::Pi() TMath::PiOver2() TMath::PiOver4() 0. // Exp
    2.5, 5., // BreitWigner
    0., 10. // Gaus
  );
#if 1 /* 0 or 1 */
  core->SetLineColor(kBlue);
  core->SetNpx(conv->GetNpx());
  core->SetRange(conv->GetXmin(), conv->GetXmax());
  core->SetParameters(conv->GetParameters()); // copy the first 7 parameters
  ngaus->SetLineColor(kBlack);
  ngaus->SetNpx(conv->GetNpx());
  ngaus->SetRange(conv->GetXmin(), conv->GetXmax());
  ngaus->SetParameters(conv->GetParameters() + 7); // copy the last 2 parameters
  core->Draw();
  ngaus->Draw("SAME"); // note: often only partially visible
  conv->Draw("SAME");
#else /* 0 or 1 */
  conv->Draw();
#endif /* 0 or 1 */
}

Thank you, this is my solution

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.