I am trying to use numpy.mgrid to create two grid arrays, but I want a way to insert a variable as the number of steps.
Without a variable number of steps, numpy.mgrid works as expected with this code:
x, y = np.mgrid[0:1:3j, 0:2:5j]
But, what I want is something like this, because I am not able to explicitly state my step number in the line of code to generate the grid arrays (the values may change due to other processes in my script):
num_x_steps = 3
num_y_steps = 5
x, y = np.mgrid[0:1:(num_x_steps)j, 0:2:(num_y_steps)j] #Try convert to complex
Is there a way to do that, that returns a result equivalent to the first method?
I tried running my 3-line code with and without parentheses and tried a couple other modifications, but nothing seemed to work.
NOTE: I tried reading this topic, but I am not sure if what that topic deals with is applicable to this problem; I don't quite understand what is being asked or how it was answered. (Also, I tried running the line of code from the answer, and it returned a MemoryError.) If said topic does answer my problem, could someone please explain it better, and how it applies to my problem?
The glitch is that j following parentheses doesn't convert to a complex number.
In [41]:(1)j
File "<ipython-input-41-874f75f848c4>", line 1
(1)j
^
SyntaxError: invalid syntax
Multiplying a value by 1j will work, and these lines give x, y equivalent to your first line:
num_x_steps = 3
num_y_steps = 5
x, y = np.mgrid[0:1:(num_x_steps * 1j), 0:2:(num_y_steps * 1j)]
I think what you are looking for is to convert the num of steps to a complex number.
num_x_steps = 3
x_steps = complex(str(num_x_steps) + "j")
num_y_steps = 5
y_steps = complex(str(num_y_steps) + "j")
x, y = np.mgrid[0:1:x_steps, 0:2:y_steps]
Related
I have noticed that it's common for beginners to have the following simple logical error. Since they genuinely don't understand the problem, a) their questions can't really be said to be caused by a typo (a full explanation would be useful); b) they lack the understanding necessary to create a proper example, explain the problem with proper terminology, and ask clearly. So, I am asking on their behalf, to make a canonical duplicate target.
Consider this code example:
x = 1
y = x + 2
for _ in range(5):
x = x * 2 # so it will be 2 the first time, then 4, then 8, then 16, then 32
print(y)
Each time through the loop, x is doubled. Since y was defined as x + 2, why doesn't it change when x changes? How can I make it so that the value is automatically updated, and I get the expected output
4
6
10
18
34
?
Declarative programming
Many beginners expect Python to work this way, but it does not. Worse, they may inconsistently expect it to work that way. Carefully consider this line from the example:
x = x * 2
If assignments were like mathematical formulas, we'd have to solve for x here. The only possible (numeric) value for x would be zero, since any other number is not equal to twice that number. And how should we account for the fact that the code previously says x = 1? Isn't that a contradiction? Should we get an error message for trying to define x two different ways? Or expect x to blow up to infinity, as the program keeps trying to double the old value of x
Of course, none of those things happen. Like most programming languages in common use, Python is a declarative language, meaning that lines of code describe actions that occur in a defined order. Where there is a loop, the code inside the loop is repeated; where there is something like if/else, some code might be skipped; but in general, code within the same "block" simply happens in the order that it's written.
In the example, first x = 1 happens, so x is equal to 1. Then y = x + 2 happens, which makes y equal to 3 for the time being. This happened because of the assignment, not because of x having a value. Thus, when x changes later on in the code, that does not cause y to change.
Going with the (control) flow
So, how do we make y change? The simplest answer is: the same way that we gave it this value in the first place - by assignment, using =. In fact, thinking about the x = x * 2 code again, we already have seen how to do this.
In the example code, we want y to change multiple times - once each time through the loop, since that is where print(y) happens. What value should be assigned? It depends on x - the current value of x at that point in the process, which is determined by using... x. Just like how x = x * 2 checks the existing value of x, doubles it, and changes x to that doubled result, so we can write y = x + 2 to check the existing value of x, add two, and change y to be that new value.
Thus:
x = 1
for _ in range(5):
x = x * 2
y = x + 2
print(y)
All that changed is that the line y = x + 2 is now inside the loop. We want that update to happen every time that x = x * 2 happens, immediately after that happens (i.e., so that the change is made in time for the print(y)). So, that directly tells us where the code needs to go.
defining relationships
Suppose there were multiple places in the program where x changes:
x = x * 2
y = x + 2
print(y)
x = 24
y = x + 2
print(y)
Eventually, it will get annoying to remember to update y after every line of code that changes x. It's also a potential source of bugs, that will get worse as the program grows.
In the original code, the idea behind writing y = x + 2 was to express a relationship between x and y: we want the code to treat y as if it meant the same thing as x + 2, anywhere that it appears. In mathematical terms, we want to treat y as a function of x.
In Python, like most other programming languages, we express the mathematical concept of a function, using something called... a function. In Python specifically, we use the def function to write functions. It looks like:
def y(z):
return z + 2
We can write whatever code we like inside the function, and when the function is "called", that code will run, much like our existing "top-level" code runs. When Python first encounters the block starting with def, though, it only creates a function from that code - it doesn't run the code yet.
So, now we have something named y, which is a function that takes in some z value and gives back (i.e., returns) the result of calculating z + 2. We can call it by writing something like y(x), which will give it our existing x value and evaluate to the result of adding 2 to that value.
Notice that the z here is the function's own name for the value was passed in, and it does not have to match our own name for that value. In fact, we don't have to have our own name for that value at all: for example, we can write y(1), and the function will compute 3.
What do we mean by "evaluating to", or "giving back", or "returning"? Simply, the code that calls the function is an expression, just like 1 + 2, and when the value is computed, it gets used in place, in the same way. So, for example, a = y(1) will make a be equal to 3:
The function receives a value 1, calling it z internally.
The function computes z + 2, i.e. 1 + 2, getting a result of 3.
The function returns the result of 3.
That means that y(1) evaluated to 3; thus, the code proceeds as if we had put 3 where the y(1) is.
Now we have the equivalent of a = 3.
For more about using functions, see How do I get a result (output) from a function? How can I use the result later?.
Going back to the beginning of this section, we can therefore use calls to y directly for our prints:
x = x * 2
print(y(x))
x = 24
print(y(x))
We don't need to "update" y when x changes; instead, we determine the value when and where it is used. Of course, we technically could have done that anyway: it only matters that y is "correct" at the points where it's actually used for something. But by using the function, the logic for the x + 2 calculation is wrapped up, given a name, and put in a single place. We don't need to write x + 2 every time. It looks trivial in this example, but y(x) would do the trick no matter how complicated the calculation is, as long as x is the only needed input. The calculation only needs to be written once: inside the function definition, and everything else just says y(x).
It's also possible to make the y function use the x value directly from our "top-level" code, rather than passing it in explicitly. This can be useful, but in the general case it gets complicated and can make code much harder to understand and prone to bugs. For a proper understanding, please read Using global variables in a function and Short description of the scoping rules?.
We have a specific set of equations whose solutions are highly dependent on the input guesses. If we use verbose given in the docs it displays a whole lot of extra information. We only want the error, or to be precise the RESIDUE. How do we obtain that obtain that?
For instance, consider the following code snippet:
import mpmath as mp
def f(x):
return [#some function of x]
y = mp.findroot(f, x0 = [1 + 1j])
print(y)
If we run the code, we get the following error:
Could not find root within given tolerance. (0.037331322115722662107 > 2.16840434497100886801e-19)
Try another starting point or tweak arguments. (the actual code has many more variables unlike the above code)
Now, we can silence this warning by setting the argument verify = False, as given in the docs.
In which case, we do get the output value, but this is not the exact output, and it has some error/residue associated with it.
Now, if we were to set up a loop and input a whole variety of starting guesses x0's, one can get as the output an arrays of corresponding y's. however, can we also get the error/residue committed in the mp.findroot solver corresponding to each y?
For instance, it would be nice if there was something like
z = mp.findroot.error(f, x0)
Thus for each guess x0, we could get a corresponding y and a corresponding z, and this would allow us to pick from all the initial guesses, which is the best one(i.e the one which produces the smallest residue)
Is there any way of finding the explicit value of this residue, and storing it in a variable?
I don't think its possible to do it in python, but instead if you want the same you can try to do this in Matlab using function handles.
fun = #(x) exp(-exp(-x)) - x; % function
x0 = [0 1]; % initial interval
options = optimset('Display','final'); % show final answer
[x fval exitflag output] = fzero(fun,x0,options)
Here x will be value and fval will be the error in the value.
I'm working a physics problem with complex numbers and think I'm setting everything up correctly but am obviously not doing something right along the way. It could be that I'm either not using the right equations or that I'm unfamiliar with how Python's handling the math, and I'm pretty sure I'm using the right stuff. I've already worked a problem using the same kind of procedure and got the correct value, so substituting my new values should
Given f = 1000, SWR = -5.9, L = 0.081, I apparently should be getting z = 1.4 - 0.23j.
Here's what I'm doing:
import numpy as np
import cmath
f = 1000 #frequency
SWR = -5.9
L = 0.081
w = 2*f*np.pi #angular frequency
c = 343 #speed of sound in air
k = w/c #wavenumber
BA = (SWR-1)/(SWR+1) #given
theta = 2*k*L-np.pi #given
z = (1+BA*np.e**(1j*theta))/(1-BA*np.e**(1j*theta)) #given
print(z)
This gives me z = (-4.699946746470462-2.3316919882323677j), obviously not what I'm being told is the correct value.
I've gone over this multiple times now and can't find anything wrong. I just again worked through the problem I already got correct and made the minor substitutions to fit these given values, and I'm still getting the returned value of z. I don't want to tell my professor his "check that your code is giving the correct results" result is wrong, but...
Am I missing something?
E: Apologies for the rough display, but I'm not sure I can type in LaTeX here. The following are what I'm working with. Furthermore, the final image shows that I worked basically the same problem correctly and that I should be able to just make some substitutions to work this one. Also note that in my code, z is actually z divided by the rhocS quantity. I'm after that, don't need to know their values.
Equation for z, BA, theta, and the worked similar problem
So, in my previous question wflynny gave me a really neat solution (Surface where height is a function of two functions, and a sum over the third). I've got that part working for my simple version, but now I'm trying to improve on this.
Consider the following lambda function:
x = np.arange(0,100, 0.1)
y = np.sin(y);
f = lambda xx: (xx-y[x=xx])**2
values = f(x)
Now, in this scenario it works. In fact, the [x=xx] is trivial in the example. However, the example can be extended:
x = np.arange(0,100, 0.1)
z = np.sin(y);
f = lambda xx, yy: ( (xx-z[x=xx])**2 + yy**2)**0.5
y = np.arange(0,100,0.1)
[xgrid, ygrid] = np.meshgrid(x,y);
values = f(xgrid,ygrid)
In this case, the error ValueError: boolean index array should have 1 dimension is generated. This is because z.shape is different from xgrid.shape, I think.
Note that here, y=np.sin(y) is a simplification. It's not a function but an array of arbitrary values. We really need to go to that array to retrieve them.
I do not know what the proper way to implement this is. I am going to try some things, but I hope that somebody here will give me hints or provide me with the proper way to do this in Python.
EDIT: I originally thought I had solved it by using the following:
retrieve = lambda pp: map(lambda pp: dataArray[pp==phiArray][0], phi)
However, this merely returns the dataArray. Suppose dataArray contains a number of 'maximum' values for the polar radius. Then, you would normally incorporate this by saying something like g = lambda xx, yy: f(xx,yy) * Heaviside( dataArray - radius(xx,yy)). Then g would properly be zero if the radius is too large.
However, this doesn't work. I'm not fully sure but the behaviour seems to be something like taking a single value of dataArray instead of the entire array.
Thanks!
EDIT: Sadly, this stuff has to work and I can't spend more time on making it nice. Therefore, I've opted for the dirty implementation. The actual thing I was interested in would be of the sort as the g = lambda xx, yy written above, so I can implement that directly (dirty) instead of nicely (without nested for loops).
def envelope(xx, yy):
value = xx * 0.
for i in range(0,N): #N is defined somewhere, and xx.shape = (N,N)
for j in range(0,N):
if ( dataArray[x=xx[i,j]][0] > radius(xx[i,j],yy[i,j])):
value[i,j] = 1.
else:
value[i,j] = 0.
return value
A last resort, but it works. And, sometimes results matter over writing good code, especially when there's a deadline coming up (and you are the only one that cares about good code).
I would still be very much interested in learning how to do this properly, if there is a proper way, and thus increase my fluency in clean Python.
I'll preface with, this is solely to satisfy my curiosity rather than needing help on a coding project. But I was wanting to know if anyone knows of a function (particularly in python, but I'll accept a valid mathematical concept) kind of like absolute value, that given a number will return 0 if negative or return that number if positive.
Pseudo code:
def myFunc(x):
if x > 0:
return x
else:
return 0
Again, not asking the question out of complexity, just curiosity. I've needed it a couple times now, and was wondering if I really did need to write my own function or if one already existed. If there isn't a function to do this, is there a way to write this in one line using an expression doesn't evaluate twice.
i.e.
myVar = x-y if x-y>0 else 0
I'd be fine with a solution like that if x-y wasn't evaluated twice. So if anyone out there has any solution, I'd appreciate it.
Thanks
One way...
>>> max(0, x)
This should do it:
max(x-y, 0)
Sounds like an analysis type question. numpy can come to the rescue!
If you have your data in an array:
x = np.arange(-5,11)
print x
[-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10]
# Now do your subtraction and replacement.
x[(x-y)>0] -= y
x[(x-y)<0] = 0
If I understand your question correctly, you want to replace values in x where x-y<0 with zeros, otherwise replace with x-y.
NOTE, the solution above works well for subtracting an integer from an array, or operating on two array of equal dimensions. However, Daniel's solution is more elegant when working on two lists of equal length. It all depends on your needs (and whether you want to venture into the world of numpy or not).
An alternative expression would be
x -= min(x, y)