0
$\begingroup$

Any idea how to connect two tilted lines with a sigmoid curve?

The ultimate goal is to get a baseline that is composed of two separate tilted lines ( with known start and end points) with a sigmoid curve in the middle. It'd look like the red line in the figure below figure . The two thick red sections are the tilted lines. The green line is the experimental data that needs to be subtracted from the red line for further analysis.

I've been looking at the logistic function. But I've been struggling with the tilted upper and lower bounds. Any suggestion or feedback would be very helpful and appreciated!

$\endgroup$
  • $\begingroup$ The simplest solution I can think of is to use a Hermite cubic, and matching function values and slopes at the two endpoints. $\endgroup$ – J. M. isn't a mathematician Apr 6 '16 at 7:29
0
$\begingroup$

If you don't know any exact function, you can always use an interpolating function. I use Interpolation with BezierFunction in mathematica to make a smooth connection. First I am going to guess some intermediate points, so I am just extending the lines a little bit and connect them.

(*Initial line*)
l1 = {{1.0, 0.35}, {5.0, 0.5}};
l2 = {{15.0, 0.25}, {20.0, 0.15}};

mid = {}; (*Choose a mid point or leave it blanck*)
f1[x_] = Fit[l1, {1, x}, x];
f2[x_] = Fit[l2, {1, x}, x];
x1 = l1[[-1, 1]];
x2 = l2[[1, 1]];
pts = Join[{#, f1[#]} & /@ Range[x1, x1 + 1, 0.5],
   mid, {#, f2[#]} & /@ Range[x2 - 1, x2, 0.5]];
f3 = Interpolation[BezierFunction[pts][#] & /@ Range[0., 1., .1]];
line[x_] := Piecewise[{{f1[x], x <= x1}, {f3[x], x1 < x < x2}, {f2[x], x >= x2}}]
Plot[line[x], {x, 0, 20}, PlotRange -> {0., 1} , Epilog -> Point[pts], Frame -> True]

enter image description here

Now I am going to guess few points which connect the black dots smoothly (black dots are just the extension of your lines). You can right click on the figure and use Get Coordinates.

mid = {{6.271, 0.5431}, {6.736, 0.5458}, {7.309, 0.5403}, {7.702, 0.5236},
       {8.167, 0.4958}, {8.453, 0.4792}, {8.739, 0.4542}, {9.204, 0.4292},
       {9.562, 0.4014}, {9.991, 0.3875}, {10.56, 0.3653}, {11.03, 0.3458},
       {11.78, 0.332}, {12.32, 0.3153}, {13.03, 0.2958}};

then rerun the second part

pts = Join[{#, f1[#]} & /@ Range[x1, x1 + 1, 0.5],
   mid, {#, f2[#]} & /@ Range[x2 - 1, x2, 0.5]];
f3 = Interpolation[BezierFunction[pts][#] & /@ Range[0., 1., .1]];
line[x_] := Piecewise[{{f1[x], x <= x1}, {f3[x], x1 < x < x2}, {f2[x], x >= x2}}]
Plot[line[x], {x, 0, 20}, PlotRange -> {0., 1} , Epilog -> Point[pts], Frame -> True]

enter image description here

See, it is connecting more smoothly. It depends on how many points you are choosing in the middle region. line[x] is the function you want. You can use a polynomial fit instead of BezierFunction to make the connecting part look as you want.

You can use any shape (sigma, wave ... whatever, just take some guess points) and once you get line[x] you can use it for further calculation.

| cite | improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you so much @Sumit ! The BezierFunction seems to be the right one! I tried the InterpolatingPolynomial function in Mathematica and found the sigmoid curve from polynomial fit is not that significant in comparison to the BezierFunction. Any idea how to make the baseline closer to the figure? So far I could only come up with manually adjusting the "pts" range to "Range[x1,x1 +4,1]" and "Range[x2 -4,x2,1]. $\endgroup$ – DavidC Apr 6 '16 at 17:03
  • $\begingroup$ hi @DavidC, I modified the answer. Hope it will help. $\endgroup$ – Sumit Apr 6 '16 at 17:59
  • $\begingroup$ That's very helpful @Sumit ! I really appreciate your reply :) $\endgroup$ – DavidC Apr 6 '16 at 20:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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