[SciPy-User] Heaviside function in vector form

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[SciPy-User] Heaviside function in vector form

Barrett B
I am trying to code the Heaviside function in vector form. There are several different versions of this, but essentially, f(x) = 1 whenever x >= 0, and f(x) = 0 whenever x < 0. Here is what I have so far (keep in mind, x is a vector here):

=========

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
#    print x
    if abs(diff) < 50: #if x is close to Theta_syn
        return 1.0/(1 + np.exp(diff))
    if x < Theta_syn:
        return 0
    return 1 #otherwise
#    return 1.0/(1 + np.exp(diff))

=========

which produces the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

BTW, if I were to comment out every line except the first and last, it runs fine.

See what I'm trying to do? Basically, I want to check whether current value of diff is not very large. But I don't know how to do this without rewriting the code to include for loops, which is what I've been trying to get away from all along?

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

Michael Sarahan
when you say

if x < Theta_syn:

you are trying to figure out the truth value of a vector.  That's what Numpy is telling you.  It doesn't make sense - only the truth value of a single value makes sense for an if statement.  Instead, you probably want a sum or something similar.

HTH.
Mike


On Sat, Jul 5, 2014 at 8:02 PM, Barrett B <[hidden email]> wrote:
I am trying to code the Heaviside function in vector form. There are several different versions of this, but essentially, f(x) = 1 whenever x >= 0, and f(x) = 0 whenever x < 0. Here is what I have so far (keep in mind, x is a vector here):

=========

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
#    print x
    if abs(diff) < 50: #if x is close to Theta_syn
        return 1.0/(1 + np.exp(diff))
    if x < Theta_syn:
        return 0
    return 1 #otherwise
#    return 1.0/(1 + np.exp(diff))

=========

which produces the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

BTW, if I were to comment out every line except the first and last, it runs fine.

See what I'm trying to do? Basically, I want to check whether current value of diff is not very large. But I don't know how to do this without rewriting the code to include for loops, which is what I've been trying to get away from all along?

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user



_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

Michael Sarahan
PS:

if abs(diff) < 50: #if x is close to Theta_syn

will also fail with this error if x is a vector.

The error message suggests any() or all(), which will return a single value representing if any or all of the values are true (respectively) - you might also consider min() or max() as sort of threshold settings, or a sum or mean of the diff vector (it will be a vector if x is a vector).


On Sat, Jul 5, 2014 at 8:15 PM, Michael Sarahan <[hidden email]> wrote:
when you say

if x < Theta_syn:

you are trying to figure out the truth value of a vector.  That's what Numpy is telling you.  It doesn't make sense - only the truth value of a single value makes sense for an if statement.  Instead, you probably want a sum or something similar.

HTH.
Mike


On Sat, Jul 5, 2014 at 8:02 PM, Barrett B <[hidden email]> wrote:
I am trying to code the Heaviside function in vector form. There are several different versions of this, but essentially, f(x) = 1 whenever x >= 0, and f(x) = 0 whenever x < 0. Here is what I have so far (keep in mind, x is a vector here):

=========

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
#    print x
    if abs(diff) < 50: #if x is close to Theta_syn
        return 1.0/(1 + np.exp(diff))
    if x < Theta_syn:
        return 0
    return 1 #otherwise
#    return 1.0/(1 + np.exp(diff))

=========

which produces the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

BTW, if I were to comment out every line except the first and last, it runs fine.

See what I'm trying to do? Basically, I want to check whether current value of diff is not very large. But I don't know how to do this without rewriting the code to include for loops, which is what I've been trying to get away from all along?

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user




_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

Barrett B
Michael Sarahan <msarahan <at> gmail.com> writes:

>
>
> PS:if abs(diff) < 50: #if x is close to Theta_synwill also fail with this
error if x is a vector.The error message suggests any() or all(), which will
return a single value representing if any or all of the values are true
(respectively) - you might also consider min() or max() as sort of threshold
settings, or a sum or mean of the diff vector (it will be a vector if x is a
vector).
>
>
> On Sat, Jul 5, 2014 at 8:15 PM, Michael Sarahan <msarahan <at> gmail.com>
wrote:
> when you sayif x < Theta_syn:you are trying to figure out the truth value
of a vector.  That's what Numpy is telling you.  It doesn't make sense -
only the truth value of a single value makes sense for an if statement. 
Instead, you probably want a sum or something similar.HTH.Mike
>

Yeah, I discovered that.

For context, here's the function that's calling Heaviside(x):

=====

def f(X, t):
    N = len(X)/3
    V = X[:N]; n = X[N:2*N]; S = X[2*N:3*N]
       
    #Equations    
    m_inf_E = 1/(1 + np.exp((E_half_m - V)/k_m))
    n_inf_E = 1/(1 + np.exp((E_half_n - V)/k_n))
    S_inf_E = 1/(1 + np.exp((E_half_S - V)/k_S))
       
    I_Ca = g_Ca * m_inf_E * (V - E_Ca)
    I_K = g_K * n * (V - E_K)
    I_S = g_S * S * (V - E_S)
       
    dV = (-I_Ca - I_K - I_S)/tau
    dV += g_inh*(E_inh - V)*Heaviside(np.dot(V, connex))/tau
    dn = (n_inf_E - n)/tau
    dS = (S_inf_E - S)/tau_S
    return np.concatenate((dV, dn, dS))

=====

(plz pretend not to notice the two lines to establish dV, lol)

The problem is that when x << Theta_syn in the Heaviside function,
np.exp(diff) is astronomically large. My whole thought process was to say
that on any given run, if x is nowhere close to Theta_syn, then Heaviside(x)
should just return 1 or 0 depending on which side we're talking about.
Simple enough, but the trick becomes:

(1) How to do this when x is a vector;
(2) How to avoid using a for loop, which would slow things down.

That is where I am stuck.

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

Michael Sarahan
In reply to this post by Michael Sarahan
I think I'd do this with indexing:

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
    output = np.ones_like(x)
    output[x<Theta_syn] = 0
    output[abs(diff < 50)] = 1.0/(1 + np.exp(diff[abs(diff < 50)]))
    return output


On Sat, Jul 5, 2014 at 8:26 PM, Michael Sarahan <[hidden email]> wrote:
PS:


if abs(diff) < 50: #if x is close to Theta_syn

will also fail with this error if x is a vector.

The error message suggests any() or all(), which will return a single value representing if any or all of the values are true (respectively) - you might also consider min() or max() as sort of threshold settings, or a sum or mean of the diff vector (it will be a vector if x is a vector).


On Sat, Jul 5, 2014 at 8:15 PM, Michael Sarahan <[hidden email]> wrote:
when you say

if x < Theta_syn:

you are trying to figure out the truth value of a vector.  That's what Numpy is telling you.  It doesn't make sense - only the truth value of a single value makes sense for an if statement.  Instead, you probably want a sum or something similar.

HTH.
Mike


On Sat, Jul 5, 2014 at 8:02 PM, Barrett B <[hidden email]> wrote:
I am trying to code the Heaviside function in vector form. There are several different versions of this, but essentially, f(x) = 1 whenever x >= 0, and f(x) = 0 whenever x < 0. Here is what I have so far (keep in mind, x is a vector here):

=========

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
#    print x
    if abs(diff) < 50: #if x is close to Theta_syn
        return 1.0/(1 + np.exp(diff))
    if x < Theta_syn:
        return 0
    return 1 #otherwise
#    return 1.0/(1 + np.exp(diff))

=========

which produces the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

BTW, if I were to comment out every line except the first and last, it runs fine.

See what I'm trying to do? Basically, I want to check whether current value of diff is not very large. But I don't know how to do this without rewriting the code to include for loops, which is what I've been trying to get away from all along?

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user





_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

Michael Sarahan
oops, typos (in abs(diff parenthesis), beware.

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
    output = np.ones_like(x)
    output[x < Theta_syn] = 0
    output[abs(diff) < 50] = 1.0/(1 + np.exp(diff[abs(diff) < 50]))
    return output


On Sat, Jul 5, 2014 at 8:42 PM, Michael Sarahan <[hidden email]> wrote:
I think I'd do this with indexing:


def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
    output = np.ones_like(x)
    output[x<Theta_syn] = 0
    output[abs(diff < 50)] = 1.0/(1 + np.exp(diff[abs(diff < 50)]))
    return output


On Sat, Jul 5, 2014 at 8:26 PM, Michael Sarahan <[hidden email]> wrote:
PS:


if abs(diff) < 50: #if x is close to Theta_syn

will also fail with this error if x is a vector.

The error message suggests any() or all(), which will return a single value representing if any or all of the values are true (respectively) - you might also consider min() or max() as sort of threshold settings, or a sum or mean of the diff vector (it will be a vector if x is a vector).


On Sat, Jul 5, 2014 at 8:15 PM, Michael Sarahan <[hidden email]> wrote:
when you say

if x < Theta_syn:

you are trying to figure out the truth value of a vector.  That's what Numpy is telling you.  It doesn't make sense - only the truth value of a single value makes sense for an if statement.  Instead, you probably want a sum or something similar.

HTH.
Mike


On Sat, Jul 5, 2014 at 8:02 PM, Barrett B <[hidden email]> wrote:
I am trying to code the Heaviside function in vector form. There are several different versions of this, but essentially, f(x) = 1 whenever x >= 0, and f(x) = 0 whenever x < 0. Here is what I have so far (keep in mind, x is a vector here):

=========

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
#    print x
    if abs(diff) < 50: #if x is close to Theta_syn
        return 1.0/(1 + np.exp(diff))
    if x < Theta_syn:
        return 0
    return 1 #otherwise
#    return 1.0/(1 + np.exp(diff))

=========

which produces the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

BTW, if I were to comment out every line except the first and last, it runs fine.

See what I'm trying to do? Basically, I want to check whether current value of diff is not very large. But I don't know how to do this without rewriting the code to include for loops, which is what I've been trying to get away from all along?

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user






_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

Barrett B
Michael Sarahan <msarahan <at> gmail.com> writes:

>
>
> oops, typos (in abs(diff parenthesis), beware.def Heaviside(x):    mult =
-100.0; diff = mult*(x - Theta_syn);    output = np.ones_like(x)    output[x
< Theta_syn] = 0    output[abs(diff) < 50] = 1.0/(1 + np.exp(diff[abs(diff)
< 50]))
>
>
>     return output
>

That got it working. Thanks!




_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: Heaviside function in vector form

David Pine
In reply to this post by Barrett B
Use NumPy "where" function.

np.where(x<0., 0., 1.)



On Saturday, July 5, 2014, Barrett B <[hidden email]> wrote:
I am trying to code the Heaviside function in vector form. There are several different versions of this, but essentially, f(x) = 1 whenever x >= 0, and f(x) = 0 whenever x < 0. Here is what I have so far (keep in mind, x is a vector here):

=========

def Heaviside(x):
    mult = -100.0; diff = mult*(x - Theta_syn);
#    print x
    if abs(diff) < 50: #if x is close to Theta_syn
        return 1.0/(1 + np.exp(diff))
    if x < Theta_syn:
        return 0
    return 1 #otherwise
#    return 1.0/(1 + np.exp(diff))

=========

which produces the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

BTW, if I were to comment out every line except the first and last, it runs fine.

See what I'm trying to do? Basically, I want to check whether current value of diff is not very large. But I don't know how to do this without rewriting the code to include for loops, which is what I've been trying to get away from all along?

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user