Value error in drawing the contourf plot - arrays

I want to draw the contourf of a certain function and my code was as follows:
xlist = linspace(0, 100, 100)
ylist = linspace(0, 100, 200)
X, Y = meshgrid(xlist, ylist)
#print "X = " + str(X)
#print "Y = " + str(Y)
Z = power_at_each_point(X, Y)
#print "Z = " + str(Z)
figure()
CP2 = contourf(X, Y, Z)
colorbar(CP2)
title('Contour Plot')
xlabel('Room-x (m)')
ylabel('Room-y (m)')
show()
The function power_at_each_point(X,Y) when I test it alone I write:
print power_at_each_point(50, 50)
and the output is -80.9187477018
which basically represents the power reached to this point in the room and it outputs a number normally but when I call it after the meshgrid command it returns an error:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
I want to take each coordinate of points in the room x-coord and y-coord and calculate the power reached at this point using the power_at_each_point method
which is supposed to return a number and I'd represent it in the contourf plot.
My guess is that the arguments (X,Y) of Z = power_at_each_point changed from being just numbers to being arrays which I don't want and that's what is causing the error.
How can I let the function Z = power_at_each_point(X,Y) take as arguments X as a number ex :1 and Y ex :2 and return a value for the power at this point so that I can represent it in my contourf plot.
Any help would be appreciated.

I've found that the function meshgrid wants a Matrix pretty much as an argument so I went ahead and created a Matrix called Z and I filled by myself the values in it and then I went ahead and entered Z as an argument to the meshgrid function:
x_list = linspace(0, 100, 100)
y_list = linspace(0, 100, 100)
X, Y = meshgrid(x_list, y_list)
Z = [[0 for x in range(len(x_list))] for x in range(len(y_list))]
for each_axes in range(len(Z)):
for each_point in range(len(Z[each_axes])):
Z[each_axes][each_point] = power_at_each_point(each_axes, each_point)
figure()
CP2 = contourf(X, Y, Z)
and that got me the result I wanted as far as I was asking here.
The points is reversed in the Z Matrix or as you can say mirrored along the horizontal but that's something i'm gonna play with so that I can get those elements in Z to match how the meshgrid actually sets it's grid points.

Related

Creating a 2D array in IDL starting from an equation

I'm trying to make a contour plot in IDL of quantity described by and equation, which here I'll take to be x^2 + y.
In order to do that, I first need to create a 2D array ("pxx").
Being a novice, I'm currently just moving my fist step into this direction and so far I've been trying to make this simpler foreach loop work:
pxx=fltarr(10, 10)
xx = indgen(10)
yy = indgen(10)
foreach k, xx do begin
pxx[k,*]=3*k
endforeach
print, pxx
But this only seems to work for the last column. Any idea on how to fix that? And how would you suggest I proceed to create a 2D array in space for the equation above?
Thank you in advance, any help is appreciated
Choose the range of x and y values you want to evaluate on:
n = 10
x = findgen(n) - (n - 1)/2.0
y = findgen(n) - (n - 1)/2.0
Expand x and y to 2-dimensional versions of themselves:
xx = rebin(reform(x, n, 1), n, n)
yy = rebin(reform(y, 1, n), n, n)
Evaluate the function:
z = xx^2 + yy
Plot:
contour, z, x, y

Matlab Array Division

I have been playing with matlab and was trying to calculate absolute relative error using two arrays. However, when I divide the two arrays, my resulting array has the same value throughout the array even though when I calculate the values by hand, they are not all the same. I was wondering why my resulting array shows the same answer for every value in the array.
Here is my code:
function [X] = absrelerror(A, B)
% Calculates absolute relative error for true value A and approximate value B.
A = linspace(sin(-pi/6), sin(pi/6), 50); %True
B = linspace(-pi/6, pi/6, 50); %Approximate
Y = abs((A-B) ./ A); %ARE equation
X = Y * 100; %convert to percent
end
I think you have approached the problem in a wrong way.
Here, the first elements of both A and B are constant. Also, the spacing between two elements of any of the vectors is also constant. Say, they are c and d where c = {A(50) - A(1)}/49 and d = {B(50) - B(1)}/49. Now, the nth value of Y is {A(1)*nc - B(1)*nd}/{A(1)*c} = {A(1)*c - B(1)*c}/A(1) which is constant. So, it's not surprising that MATLAB is giving a constant value in Y.
If I have understood correctly what you are trying to do, then you should do it in the following way:
%A = linspace(sin(-pi/6), sin(pi/6), 50); %True
B = linspace(-pi/6, pi/6, 50); %Approximate
%Y = abs((A-B) ./ A); %ARE equation
%X = Y * 100; %convert to percent
A = sin(B);
X = abs((A-B)./A) * 100;
fprintf('%f ', X)
The output is:
4.719755 4.330958 3.960262 3.607413 3.272170 2.954306 2.653606 2.369868 2.102903 1.852533 1.618593 1.400927 1.199394 1.013862 0.844209 0.690325 0.552111 0.429477 0.322344 0.230643 0.154315 0.093311 0.047592 0.017130 0.001903 0.001903 0.017130 0.047592 0.093311 0.154315 0.230643 0.322344 0.429477 0.552111 0.690325 0.844209 1.013862 1.199394 1.400927 1.618593 1.852533 2.102903 2.369868 2.653606 2.954306 3.272170 3.607413 3.960262 4.330958 4.719755

How to Create asteroids on the x and y axes

I'm doing Asteroids (Atari) in C. I designed the ADT for asteroids, all the ADT is related to 1 asteroid.
I need to create an asteroid in a random position, but random within (0, y) or (x, 0)
I have my function asteroid_create():
asteroid_t *asteroid_create(float x, float y, float radio){
asteroid_t *ast = malloc(sizeof(asteroid_t));
ast->x_pos = x;
ast->y_pos = y;
ast->radio = radio;
ast->vx = rand_float((1000/ast->radio)-100,(1000/ast->radio)+100);
ast->vy = rand_float((1000/ast->radio)-100,(1000/ast->radio)+100);
ast->angle = rand_float(0,2*PI);
size_t rock_rand = rand() % ASTEROIDS_TYPES;
ast->name_rock = rocks_dictionary[rock_rand];
return ast;
}
That creates an asteroid with certain fixed variables. Then, in another file, I create a list of asteroids and I'm inserting as many asteroids I need.
bool asteroids_insert(list_t* l){
asteroid_t *ast = asteroid_create(rand_float(0,WINDOW_WIDTH),rand_float(0,WINDOW_HIGH),AST_INITIAL_RADIO);
if(!list_append(l,ast))
return false;
return true;
}
In the main:
for(size_t i=0; i< ASTEROIDS_INITIAL;i++){
asteroids_insert(list_asteroids);
}
In this way, I am creating asteroids anywhere on the screen. I only need them to be generated on the y axis or the x axis.
The way I am doing it, I can't think of how I can do what I need. How can I do it so that asteroid_create() receive as a parameter positions in (0, y) or (x, 0) randomly?
Imagine you bend the y axis down to the left, so that in effect it becomes the "negative part" of the x axis.
Generate a random number value between -MAX_Y and +MAX_X.
If the resulting number is 0 your point is (0, 0); if it's positive, your point is (value, 0), otherwise it's (0, -value).
Note: if your x axis is larger than y axis, this will make it more probable to generate points on the x axis.

Spiral loop on a matrix from a point

I have a 2D grid as follow and want to start from X, Y and save the corner of a window (W) and overlap of (OP). I have tried these codes, but non of them are fit to my purpose.
As it is demonstrated, I want to start from a random point (black cell) and save the corner locations (shown by black circles) of each new window in a spiral loop. The algorithm should be used for any grid sizes (not square necessarily) and any start point locations.
Matlab also has a function (spiral) that is similar to what I want, but it does not take a grid, window size and overlap (OP).
I expect to have the following output for this figure: (8,12)
(11,12)
(11,9)
(8,9)
(4,9)
(4,12)
(4,15)
...
I am using the following codes which starts from a corner and fill the matrix step-by-step using the defined W, OP and Matrix size:
W = [10 12];
OP = [4 3];
M = zeros(100,110);
for i=[1:W(1)-OP(1):size(M,1)-W(1), size(M,1)-W(1)+1]
for j=[1:W(2)-OP(2):size(M,2)-W(2), size(M,2)-W(2)+1]
block = rand(W(1),W(2));
M(i:i+W(1)-1, j:j+W(2)-1) = block;
imagesc(M); axis equal tight xy
pause(.1)
end;
end;
So, in a more clear way, how should I change the "above" code in order to start from a location(x,y) and spirally fill the whole matrix according to W, OP and size(M).
Thanks!
The basic problem
Let the data be defined as:
step = 3; %// step size
x0 = 8; %// x coordinate of origin
y0 = 12; %// y coordinate of origin
N = 32; %// number of steps
Then the coordinates of the spiral can be obtained as values in the complex plane as follows†:
z = x0+1j*y0 + step*cumsum([0 -1j.^(-floor(sqrt(4*(0:N)+1))-1)]);
Of course, the x and y coordinates are then
x = real(z);
y = imag(z);
With the example values given above, plot(z,'o-') (or plot(x,y,'o-')) produces the graph
† The key was to generate the sequence 1,2,3,3,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,8... I'm indebted to OEIS for solving that part. The sequence turns out to be the integer part of the square root of 4n+1, for n=1,2,3,...
How to include overlap and window size
To take into account overlap, following Daniel's suggestion, subtract its value from step.
To consider window size, N should be large enough so that the spiral reaches some point out of the window boundary; and then only the preceding points would be kept.
Since it's difficult to compute in advance how large N should be, one possible approach is to exponentially increase N in a loop until it is large enough. The exponential increase assures that the number of loop iterations will be small. The code below uses powers of 2 for N.
%// Data
step = 3; %// step size
overlap = 1; %// overlap
x0 = 20; %// x coordinate of origin
y0 = 15; %// y coordinate of origin
xmin = 0; %// window boundary: min x
xmax = 40; %// window boundary: max x
ymax = 30; %// window boundary: min y
ymin = 0; %// window boundary: max y
%// Computations
stepov = step-overlap;
N = 8; %// Initial value. Will be increased as needed
done = false;
while ~done
z = x0+1j*y0 + stepov*cumsum([0 -1j.^(-floor(sqrt(4*(0:N)+1))-1)]);
%// compute coordinates of N points
ind = find(real(z)<xmin | real(z)>xmax | imag(z)<ymin | imag(z)>ymax, 1);
%// find index of first z out of boundary, if any
done = ~isempty(ind); %// exit if we have reached outside window boundary
N = N*2; %// increase number of steps for next try
end
z = z(1:ind-1); %// only keep values that are within the boundary
x = real(z);
y = imag(z);
With the data indicated in the code, the obtained graph is as follows. Note that the last point is (38,0). The next point would be (38,-2), which is outside the window boundary.
Here is a piece of code which produces the expected output. There where only minor changes to the spiral_generic necessary to match your requirements:
function demo()
spiral_generic([10,11],[3,4])
W = [10 12];
OP = [4 3];
%make sure your start point is really on the grid of r and c, this is not checked!
start = [19,28];
M = zeros(100,110);
r=[1:W(1)-OP(1):size(M,1)-W(1), size(M,1)-W(1)+1];
c=[1:W(2)-OP(2):size(M,2)-W(2), size(M,2)-W(2)+1];
startindex=[find(r==start(1),1,'first'),find(c==start(2),1,'first')];
A=spiral_generic([numel(r),numel(c)],startindex);
[~,idx]=sort(A(:));
[ridx,cidx]=ind2sub(size(A),idx);
%blocks contains the lower left corners in order of processing.
blocks=[r(ridx);c(cidx)];
for blockindex=blocks
block = rand(W(1),W(2));
M(blockindex(1):blockindex(1)+W(1)-1, blockindex(2):blockindex(2)+W(2)-1) = block;
imagesc(M);
pause(.1)
end
end
function A = spiral_generic(n, P)
% Makes NxN matrix filled up spirally starting with point P
r = max([P - 1, n - P]); % Radius of the bigger matrix
M = spiral(2 * r + 1); % Bigger matrix itself
M = permute(M,[2,1]); % changing start direction of the spiral
M = M(:,end:-1:1); % chaning spin orientation
C = r + 1 - (P - 1); % Top-left corner of A in M
A = M(C(1):C(1)+n(1)-1, C(2):C(2)+n(2)-1); % Get the submatrix
[~, order] = sort(A(:)); % Get elements' order
A(order) = 1:(n(1)*n(2)); % Fill with continous values
end

Function with input (a,b,c) that results in output (x,z,y)

So I'm working on a process that will allow me to calculate subobject normals for models I am putting into a game. Basically, I know how to calculate them but I need to create a function that can use this bit of code.
local sin, asin = math.sin, math.asin
local deg, rad = math.deg, math.rad
math.sin = function (x) return sin(rad(x)) end
math.asin = function (x) return asin(deg(x)) end --Makes math.sin read in degrees instead of radians
x = function (sin (a))
z = function (sin (b))
y = function (sin (c))
d = {a, b, c}
end
e = {x, z, y}
end
repeat
print("Enter a value for x:")
a = io.read("*number") -- read a number
print(math.sin(a))
print("Do you want to repeat? Type 1 to repeat")
a = io.read("*number")
until a ~= 1
The way it works is that the sine of the angle that the subobject was rotated becomes the normal value on that axis. (z = b because Blender operates in X-Y horizontal and the game is in X-Z horizontal)
Basically, I am looking for a function the allows me to input "array d" and get the output displayed as "array e" instead of that single output function. a, b, and c are variables, not constants.
A function in python can be defined as -
def myfunc(a,b,c):
x = sin (a)
z = sin (b)
y = sin (c)
return x,y,z
or you can input an array -
def myfunc(arr):
x = sin (arr[0])
z = sin (arr[1])
y = sin (arr[2])
return {x,y,z}
Notice that you can return multiple numbers stored in different ways, depending on your needs.

Resources