-1

I'd like to fit a spherical formula with 2 structures, but I cant find a way to do it. "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()" on the last line.

My goal is to fit experimental data with the curve_fit function of scipy, or other libraries. My code:

    import numpy as np
    from scipy.optimize import curve_fit

    xdata = np.asarray(df['exp_x'])
    ydata = np.asarray(df['exp_y'])


    def Spherical(x, comp1, sill_comp2, range_comp2, sill_comp3, range_comp3):
        if x <= range_comp2:
            comp2 = sill_comp2 * (1.5 * (x / range_comp2) - 0.5 * (x / range_comp2) ** 3)
        else:
            comp2 = sill_comp2

        if x < range_comp3:
            c3 = sill_comp3 * (1.5 * (x / range_comp3) - 0.5 * (x / range_comp3) ** 3)
        else:
            c3 = sill_comp3

        y = comp1 + comp2 + comp3
        return y

    parameters, covariance = curve_fit(Spherical, xdata, ydata)
    parameters

Thanks !

Vnc J
  • 47
  • 6
  • Help anybody ? :'( – Vnc J Sep 14 '22 at 02:07
  • There is quite a bit of information lacking in your question. Most importantly, it's not reproducible, because we don't have your input data. Also, you use `c3`, but I assume you mean `comp3`, since `c3` isn't used later, while `comp3` is used near the end, without being set. – 9769953 Sep 14 '22 at 12:33

1 Answers1

0

There's a few pieces of information missing in your question, but I can have a guess from the given error.

You're comparing an array to an single value, you'll get an array of bools. You can't use an array of bools in an if-statement (how is an array true or false?), that is what the error is about. A simple search would have shown countless examples of that issue. Though the solution can differ from case to case.

I think you want something like

def Spherical(x, comp1, sill_comp2, range_comp2, sill_comp3, range_comp3):
    comp2 = np.empty_like(x)
    low = x <= range_comp2
    comp2[low] = sill_comp2 * (1.5 * (x / range_comp2) - 0.5 * (x / range_comp2) ** 3)
    comp2[~low] = sill_comp2


    comp3 = np.empty_like(x)
    low = x < range_comp3
    comp3[low] = sill_comp3 * (1.5 * (x / range_comp3) - 0.5 * (x / range_comp3) ** 3)
    comp3[~low] = sill_comp3

    y = comp1 + comp2 + comp3
    return y

This uses NumPy indexing to separate the two "branches" of the original statement. It generally is the way to rewrite an if-else to using NumPy arrays.

Note that I've replaced c3 with comp3, since otherwise the calculation of c3 in the original example code is not used, while comp3 is pulled out of nowhere to calculate y.

9769953
  • 10,344
  • 3
  • 26
  • 37