Home > Net >  ValueError: `fun` must return at most 1-d array_like. f0.shape: (2, 100)
ValueError: `fun` must return at most 1-d array_like. f0.shape: (2, 100)

Time:08-17

I'm trying to find the intersection of lines after solving a system of equations, and it shows 'ValueError: fun must return at most 1-d array_like. f0.shape: (2, 100)'. Not really sure where I got wrong.

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import least_squares
import scipy.interpolate, scipy.optimize


k1 = 10 ** (-9.25)
k2 = 10 ** (-18.26)
k3 = 10 ** (-35.91)
logk = 11.96
pH_x = np.linspace(0, 14, 100)
ni_total = 0.1
n_total = 1.2
T_ = 298
h = 10 ** (-pH_x)
def equations(p):
    nh4, nio2 = p
    f = 10 ** (logk - 2 * pH_x)
    ni2pfree = f/(1   f / ni_total)
    nh3 = k1 * nh4 / h
    nin4p2 = k2 * (nh4 ** 4) / (h ** 2)
    nin6p2 = k3 * (nh4 ** 6) / (h ** 4)
    return (n_total-nh3-4*nin4p2-6*nin6p2-nh4,
            ni_total - ni2pfree - nin4p2- nin6p2- nio2)
res = least_squares(equations, (0.1, 0.1), bounds=((0, 0), (n_total,ni_total )),method='dogbox',xtol=1e-12)
nh4 =res.x[0]
nio2 =res.x[1]
f = 10 ** (logk - 2 * pH_x)
ni2pfree = f / (1   f / ni_total)
nh3 = k1 * nh4 / h
nin4p2 = k2 * (nh4 ** 4) / (h ** 2)
nin6p2 = k3 * (nh4 ** 6) / (h ** 4)

y1 = -0.2405   0.0296 * np.log10(ni2pfree)
y2 = 0.1102-0.0592*pH_x
interp1 = scipy.interpolate.InterpolatedUnivariateSpline(pH_x, y1)
interp2 = scipy.interpolate.InterpolatedUnivariateSpline(pH_x, y2)

def difference(pH_x):
    return np.abs(interp1(pH_x) - interp2(pH_x))

x_at_crossing = scipy.optimize.fsolve(difference, x0=0.0)
plt.plot(x_at_crossing, interp1(x_at_crossing), 'cd', ms=7, label='fsolve method')
plt.show()

CodePudding user response:

The function least_squares() expect the first argument fun with the signature fun(x, *args, **kwargs) where the argument x is an ndarray of shape (n,), while in your case it has shape (2,100).

This error arises from the way you return the function equation():

return (n_total-nh3-4*nin4p2-6*nin6p2-nh4, ni_total - ni2pfree - nin4p2- nin6p2- nio2) returns a tuple of shape (2,) and not an array of shape (n,).

Changing your return line to:

return np.array([n_total-nh3-4*nin4p2-6*nin6p2-nh4, ni_total - ni2pfree - nin4p2- nin6p2- nio2]).flatten()

would allow the code to run entirely, but I believe the answer you'd get is not correct, since this 'solution' only flattens the array that had shape (2,100) to shape (n,).

  • Related