0

I am trying to plot a 3D graph, using a re-existing function to generate the Z values. However, this is yielding the error "The truth value of an array with more than one element is ambiguous". This seems strange, as I am able to generate a list of Z values using the same function and y,x values, but once I include the 3D graphing code the error occurs.

My graphing code is:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from matplotlib import cm
 
def f(tau,tau_b):                             #re-use society welfare function of tau & tau_b, using corr=0.6
    Z = society_welfare2 (0.6, tau, tau_b)
    return Z

xgrid=np.linspace(1e-5, 1-1e-5,100)   #tau grid
ygrid=np.linspace(1e-5, 1-1e-5,100)   #tau_b grid
tau,tau_b=np.meshgrid(xgrid,ygrid)

fig=plt.figure(figsize=(8,6))
ax=fig.add_subplot(111,projection='3d')
ax.plot_surface(tau,
                tau_b,
                f(tau,tau_b),
                rstride=2,cstride=2,
                cmap=cm.jet,
                alpha=0.7,
                linewidth=0.25)
ax.set_zlim(-0.5,1.0)
plt.show()

My society_welfare2 function code:

def society_welfare2 (corr, tau, tau_b):
    
    cov   = [[1,corr], [corr,1]]   #covariance
    epsilon_start,b_start = np.random.multivariate_normal(mean, cov, sample_N).T 

    epsilon     = np.exp(epsilon_start)  #to ensure epsilon positive
    b     = np.exp(b_start)              #to ensure b positive

    indv_welfares = []
    
    def GBC (t_o):
        taxes_paid = []

        for i in range(sample_N):                     #loop over all agents to find their C1,C2,L

            def consumption_functions(Lguess,epsilon=epsilon,b=b):
                C2 = (((1-tau)*epsilon[i]*w*Lguess) +(1-tau_b)*b[i] + ((t_o)/(1+r)))/((1/((beta**(1/gamma))*((1+r)**(1/gamma)))) + (1/(1+r)))
                C1 = C2 /((beta**(1/gamma))*(1+r)**(1/gamma))
                return -Utility(C1,C2,Lguess)

            result = minimize_scalar(consumption_functions,bounds=(0,1),method='bounded', args=(epsilon, b))

            opt_L = result.x
        
            opt_C1=(((1-tau)*(epsilon[i])*w)/(opt_L**sigma))**(1/gamma)
        
            opt_C2=(opt_C1)*((beta**(1/gamma))*(1+r)**(1/gamma))
        
            income_tax = tau*(epsilon[i])*w*opt_L         
            bequest_tax = tau_b*(b[i])                 
            taxes_paid.append(income_tax)        
            taxes_paid.append(bequest_tax)   
            
            welfare_func = opt_C1**(1-gamma)/(1-gamma)-opt_L**(1+sigma)/(1+sigma) + beta*(opt_C2**(1-gamma)/(1-gamma))
            indv_welfares.append(welfare_func)
    
        total_tax_revenue = sum(taxes_paid)  
    
        return total_tax_revenue - (10000*t_o)

    result1 = minimize_scalar(GBC,bounds=(1e-5, 100000),method='bounded')
    
    opt_t_o = result1.x
    
    total_welfare = sum(indv_welfares)
    return total_welfare   

The full traceback error code:

ValueError                                Traceback (most recent call last)
<ipython-input-19-3633f4a9db76> in <module>
     18 ax.plot_surface(tau,
     19                 tau_b,
---> 20                 f(tau,tau_b),
     21                 rstride=2,cstride=2,
     22                 cmap=cm.jet,

<ipython-input-19-3633f4a9db76> in f(tau, tau_b)
      7 
      8 def f(tau,tau_b):                             #re-use society welfare function of tau & tau_b, using corr=0.6
----> 9     Z = society_welfare2 (0.6, tau, tau_b)
     10     return Z
     11 

<ipython-input-17-321a709b9684> in society_welfare2(corr, tau, tau_b)
     61         return total_tax_revenue - (10000*t_o)
     62 
---> 63     result1 = minimize_scalar(GBC,bounds=(1e-5, 100000),method='bounded')
     64 
     65     opt_t_o = result1.x

/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/_minimize.py in minimize_scalar(fun, bracket, bounds, args, method, tol, options)
    798         if isinstance(disp, bool):
    799             options['disp'] = 2 * int(disp)
--> 800         return _minimize_scalar_bounded(fun, bounds, args, **options)
    801     elif meth == 'golden':
    802         return _minimize_scalar_golden(fun, bracket, args, **options)

/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/optimize.py in _minimize_scalar_bounded(func, bounds, args, xatol, maxiter, disp, **unknown_options)
   1956     rat = e = 0.0
   1957     x = xf
-> 1958     fx = func(x, *args)
   1959     num = 1
   1960     fmin_data = (1, xf, fx)

<ipython-input-17-321a709b9684> in GBC(t_o)
     41                 return -Utility(C1,C2,Lguess)
     42 
---> 43             result = minimize_scalar(consumption_functions,bounds=(0,1),method='bounded', args=(epsilon, b))
     44 
     45             opt_L = result.x

/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/_minimize.py in minimize_scalar(fun, bracket, bounds, args, method, tol, options)
    798         if isinstance(disp, bool):
    799             options['disp'] = 2 * int(disp)
--> 800         return _minimize_scalar_bounded(fun, bounds, args, **options)
    801     elif meth == 'golden':
    802         return _minimize_scalar_golden(fun, bracket, args, **options)

/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/optimize.py in _minimize_scalar_bounded(func, bounds, args, xatol, maxiter, disp, **unknown_options)
   2015             print("%5.0f   %12.6g %12.6g %s" % (fmin_data + (step,)))
   2016 
-> 2017         if fu <= fx:
   2018             if x >= xf:
   2019                 a = xf

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
NK12345
  • 23
  • 4
  • Please provide full details -- where does the error occur? – GoodDeeds Apr 21 '21 at 22:26
  • 2
    Someplace you are trying to use a boolean array in an context that expects a simple True/False. Where? That's for you to tell us! We don't like to guess! – hpaulj Apr 21 '21 at 22:33
  • 1
    You have to decide if you want [all](https://numpy.org/doc/stable/reference/generated/numpy.all.html) True's along an axis or [any](https://numpy.org/doc/stable/reference/generated/numpy.any.html) True's along an axis. We don't know what you want or need. If you search SO with the Error message and read though all the Q&A's in the results you will get a feel for what the issue is. – wwii Apr 21 '21 at 22:33
  • Here is one fairly concise explanation: [https://stackoverflow.com/a/22175728/2823755](https://stackoverflow.com/a/22175728/2823755) – wwii Apr 21 '21 at 22:37
  • @GoodDeeds The error occurs after I run the first code chuck, to generate the 3D graph. – NK12345 Apr 21 '21 at 22:42
  • 1
    Was there anything in the error message labeled 'traceback'? We want to see that. – hpaulj Apr 21 '21 at 22:43
  • I'm sorry, I don't understand where the all/any true boolean comes into play. The society_welfare2 function takes in tau, tau_B and returns a number value. What is there to be true? – NK12345 Apr 21 '21 at 22:43
  • 1
    @hpaulj Sure, I'll edit the post to include the full error code – NK12345 Apr 21 '21 at 22:46

1 Answers1

0

The lowest point the trace back is

if fu <= fx:

That's comparing two variables in an if. That will work if fu and fx are scalars, or single value arrays. But if either is a multivalue array if will raise this error.

Our task at this point is to trace those variables back to your code. I suspect you are providing arrays for some parameter, where they/is should be a scalar.

Looking at the top. It occurs when you ask for the plot, but a parameter is a function call:

f(tau,tau_b)

and on through a function calls to the minimize on the GBC function. I think that GBC is the func in:

fx = func(x, *args)

Which raises the question, what exactly does GBC return? It's being used in a _minimize_scalar, so it should return exactly one value.

What is its return expression?

return total_tax_revenue - (10000*t_o)

Do you think you can take the analysis from there?

Now do you see why we insist on seeing the traceback. The error is in your code, but the sequence getting there is long, and not obvious from simply reading the code.

edit

Oops, I see another level of minimize, one that uses

consumption_functions

It has several parameters, epsilon and b. I suppose we can deduce what those are. But what is

Utility

The fu <= fx appears to be testing the fx return value against a bound fu. Assuming the bound is scalar, then the value fx must be an array. Is it???

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • The point of GBC is just to set up a function in order to root-find (that is, use minimize scalar to find a # such that 0 = total_tax_revenue - (10000*t_o)). – NK12345 Apr 21 '21 at 23:19
  • I don't care about the purpose. **I want to know what it produces.** Does it a produce one number as required by the minimize code, or does it produce an array, several values, as the error suggests. – hpaulj Apr 21 '21 at 23:22
  • On further reading the traceback, I hit a big unknown `Utility`. See my edit. – hpaulj Apr 21 '21 at 23:36
  • I thought the minimize_scalar of GBC would produce just 1 root (so yes, one value not an array). Whenever I run that code, it produces just 1 value. Utility is a function that returns 1 value as well. – NK12345 Apr 21 '21 at 23:53