2

I have the following code written in python 2.7. Here I've defined two function, a cosine function and an exponential function and I need to multiply these functions to a float Value, but I am getting this error. I assume we can't multiply a float value to a function in list() format... I would be grateful if someone tell me how can I do this. Thanks in advance. Here is my code :

import numpy as np
import math
import cmath

delta  = 2.0*math.pi*1.46*((1.0/1530)-(1.0/1550))

#defining main func
def apFunc(x):
    return np.exp(-4*math.log(2)*((x-(5/2))/5)**2)*(1+math.cos((2*math.pi/0.001)*x))
Domain = list(np.arange(0,5,0.001))
APF    = map(apFunc,Domain)

#defining modulation function 
def modFunc(x):
    return (1+math.cos((2*math.pi/0.001)*x))
d      = list(np.arange(0,5,0.001))
mod    = map(modFunc,d)

#making sig and kaa functions
sgima  = (2*math.pi/1530)*APF
sig    = sigma + delta
kaa    = (math.pi/l1530)*mod
gamma  = math.sqrt(sig**2 + kaa**2)

Vahid Talebi
  • 175
  • 1
  • 9
  • 1
    For lists, `*` and `+` are not math operations, they repeat and join lists. It's `numpy` arrays that can do the math on multiple elements. Also be ware that `math` functions can only work on single numbers, not lists or arrays. – hpaulj Feb 26 '21 at 16:30
  • If you move this code on to Python3 (current), this use of `map` will need changing. – hpaulj Feb 26 '21 at 16:31
  • @ hpaulj please look at the code once again, How can I do this: `sgima = (2*math.pi/1530)*APF` – Vahid Talebi Feb 26 '21 at 16:36
  • 1
    I see `math.cos()`, `math.pi` etc. is there a specific reason not to stick to numpy? This would solve your problem by itself. – norok2 Feb 26 '21 at 16:39
  • 1
    Why do you use `np.exp` but `math.log` in the same expression? – hpaulj Feb 26 '21 at 16:39
  • 1
    Thanks sir problem solved, once I changed the code and get same error but then I saw just one of the math. s was forgotten :-) – Vahid Talebi Feb 26 '21 at 16:56

2 Answers2

2

Sticking to NumPy (and specifically avoiding math/cmath altogether) would just solve the issues you are observing, by completely avoiding non-broadcast-friendly containers / operations:

import numpy as np


delta = 2.0 * np.pi * 1.46 * ((1.0 / 1530) - (1.0 / 1550))


def apFunc(x):
    return np.exp(-4 * np.log(2) * ((x - (5 / 2)) / 5) ** 2) * (
        1 + np.cos((2 * np.pi / 0.001) * x)
    )


def modFunc(x):
    return 1 + np.cos((2 * np.pi / 0.001) * x)


d = np.linspace(0.0, 5.0, 5000)
APF = apFunc(d)
mod = modFunc(d)

# making sig and kaa functions
sigma = (2 * np.pi / 1530) * APF
sig = sigma + delta
kaa = (np.pi / 1530) * mod
gamma = np.sqrt(sig ** 2 + kaa ** 2)

(I also fixed some typos here and there, and cleaned/reordered a little bit, although it is not yet fully PEP8-compliant)

Note that I have replaced the use of np.arange() with an equivalent call to np.linspace(), since as-per its documentation: "When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use numpy.linspace for these cases."

norok2
  • 25,683
  • 4
  • 73
  • 99
  • Thank you norok2 this solved the problem, but why do you use `np.linspacee()` instead of `np.arange()` ?? – Vahid Talebi Feb 26 '21 at 16:57
  • 1
    "When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use numpy.linspace for these cases." This is so because if the step is not represented exactly, summing it over and over will just cause the error to accumulate, and this may lead to inconsistent result (one data point off from what you could expect with exact math). – norok2 Feb 26 '21 at 17:03
  • 1
    @VahidTalebi see also [How to use a decimal range() step value?](https://stackoverflow.com/a/477635/5218354) – norok2 Feb 26 '21 at 17:15
  • Now I am adding another element which is `deltz = (5*(10.0**6))/50 f11=complex(np.cosh(gamma*deltz),-(sig/gamma)*np.sinh(gamma*deltz))` and getting this error `only length-1 arrays can be converted to Python scalars` – Vahid Talebi Feb 26 '21 at 17:47
  • 1
    it's same issue. Just use `x + 1j * y` instead of `complex(x, y)`. – norok2 Feb 26 '21 at 20:28
  • I have a hyperbolic function there and the problem is because of that I think. here is the function : `f11=complex(np.cosh(gammab*deltz),-(sig/gammab)*np.sinh(gammab*deltz))` when I write in `x+1j*y` format a warning occurs saying `overflow encountered in sinh` – Vahid Talebi Feb 26 '21 at 20:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229271/discussion-between-vahid-talebi-and-norok2). – Vahid Talebi Feb 26 '21 at 21:21
1

whoo, lots in there.

Friendly tip- providing the stack trace makes it easier to help you, as would reducing the code to just the important parts.

For your actual problem -

mod is map(modFunc,d)

map returns a list so mod = [..., ...] then kaa = (pi) * mod

or (pi) * [..., ...]

Which doesn't make much sense. You probably want a map there as well?

Paul Becotte
  • 9,767
  • 3
  • 34
  • 42
  • Thanks dear Paul for your tip and answer. All I need here is making '''sig''' and '''kaa''' and I have those two map functions as you said is in the form of list. maybe I need to define sig and kaa as map??? – Vahid Talebi Feb 26 '21 at 16:24
  • 1
    I have no idea what you're actually trying to do :) All I know is that you can't multiply a list by a float (and multiplying it by an int wouldn't be what you want anyway). If what you want is "multiply every value of this list by this value and store the result in a new list" map would be the right choice. – Paul Becotte Feb 26 '21 at 16:51
  • Thanks Paul I just changed all math libs to numpy and the problem solved – Vahid Talebi Feb 26 '21 at 16:59