Related
I have a question regarding using the sine function. When I entered the number 4, 8, .., etc., really I supposed to get the number somewhere very close to zero, but not exactly (Ex. 0.001, 0.0003, etc). However, I got the number y = 1.224 when x = 4, and y = -2.449 when x = 8. This should be incorrect. I don’t understand the problem here. Does anyone know what is going on here?
[Photo of my code and a sin graph - Link]
https://ibb.co/6YCWW90
[Code]
import math
import matplotlib.pyplot as plt
import numpy as np
x = [0, 1, 2, 3, 4, 5, 6, 7, 8]
y = [math.sin(0.25 * math.pi * i) for i in x]
print(y)
plt.plot(x, y)
plt.show()
Everything works.
When i is 0, then "0.25 * math.pi * i" is precisely 0 and when you calculate the sine, you get exactly 0.0.
When i is 4, then calculating "0.25 * math.pi * i" results in a number very close to PI, but the accuracy is limited. If you calculate the sine, you get a number which is very, very close to zero, but because of limited accuracy, not exactly zero. The result is 1.2246467991473532e-16. NOTE: it is 0.00000000000000012246467991473532, not 1.224 what your wrote in your question.
Similarly rounding errors result in -2.4492935982947064e-16 for i equal to 8. The argument is not exactly 2 PI and rounding errors result in a value slightly different than 0.0.
Again -2.4492935982947064e-16 is -0.00000000000000024492935982947064 and not -2.449 as you wrote in your question.
I'm having difficulty creating a 2 y axis graph in Octave. Currently I can make the 2 line graph. However, I haven't been able to find a function that will help me with my problem. I have tried using the plotyy function but I am not sure if you can use this function with two left side axis line graphs and one right side graph. Here is code I have written so far in my attempt.
labels = ["Data 1"; "Data 2"; "Data 3"; "Data 4"; "Data 5"]
y1 = [137, 15, 2, 3, 37]
y2 = [43, 1, 67, 97, 41]
x = [1, 2, 3, 4, 5]
y3 = [0, .2, .3, .104, .09]
z1 = plot(x, y1, y2)
plot(x, y1, y2)
hold on
plot(x, y2)
xlabel("Version")
yyaxis left
ylabel("Y axis")
set(gca,'XTickLabel',labels)
yyaxis right
z = bar(x,y3)
z
yyaxis right
ylabel("Data")
While plotyy is the command to plot two normal plots using distinct left and right yaxes, I don't think you can do what you were trying to do with it. (i.e. mix two plots with a bar chart). However, what plotyy does is literally a simple case of overlaying two axes at the same position and making one 'see-through'. So you can use the same approach in general.
Here's your example above re-worked to achieve this (plus some extra bling):
x = [1, 2, 3, 4, 5]; labels = ["Data 1"; "Data 2"; "Data 3"; "Data 4"; "Data 5"];
y1 = [137, 15, 2, 3, 37]; y2 = [43, 1, 67, 97, 41]; y3 = [0, .2, .3, .104, .09];
ax_left = axes('position', [0.15, 0.12, 0.7, 0.82]); % manually positioned
plot (x, y1, 'r-', 'linewidth', 3); hold on
plot (x, y2, 'g:', 'linewidth', 3); hold off
set (ax_left, ...
'fontsize', 16, 'fontweight', 'bold', 'labelfontsizemultiplier', 1.2, ...
'color', 'none', ... % makes 'background' see-through
'box', 'off', ... % prevents left axis ticks in the right axis
'xlim', [0, 6], 'ylim', [0, 150], 'xtick', x, 'xticklabel', labels);
xlabel('Version'); ylabel('Left Y-Axis');
ax_right = axes('position', [0.15, 0.12, 0.7, 0.82]); % same position as above
bar (x, y3, 0.5, 'facecolor', [0, 0.5, 1]); % nice narrow light blue columns
set (ax_right, ...
'fontsize', 16, 'fontweight', 'bold', 'labelfontsizemultiplier', 1.2, ...
'yaxislocation', 'right', ...
'ycolor', [0, 0.5, 1], ... % same nice light blue color as bar chart
'box', 'off', 'xlim', [0, 6], 'ylim', [0, 0.35], 'xtick', []);
ylabel('Data');
% ensure axes are stacked in the order you want them to appear (bottom to top)
axes(ax_right);
axes(ax_left);
def call(nums):
nums[:] = [x for x in nums if x != 4]
numbers = [4, 5]
print(numbers)
call(numbers)
print(numbers)
The output for the above code is:
[4, 5]
[5]
But if you remove the "[:]", the output becomes the following:
[4, 5]
[4, 5]
I know that [:] makes a copy of the full list, but why the function argument is modified in one case and not in the other?
As you suspected the issue is hiding in the slicer in line:
nums[:] = [x for x in nums if x != 4]
Python is "pass by value" which means that you're not passing the pointer numbers into the function, but a copy of it. So re-assigning a value to a copy of the reference will not change the original reference.
But, when you use the slicer, you're accessing the object behind the reference and changing it directly which is why you see the side effect after you exit the function - when using the "slice".
As Python passes objects by reference, when you execute your function with nums[:] = ... line, you change actual list that you've passed from outside, numbers. When you change line to nums = ..., you just overwrite local variable called nums, without affecting numbers array.
In Python, you can not only slice collections to read them, but you can assign to slices, replacing sliced content.
For example:
>>> a = [0, 1, 2, 3, 4, 5]
>>> a[1:4]
[1, 2, 3]
If you assign to slice, it will replace part of original array:
>>> a[1:4] = ['z']
>>> a
[0, 'z', 4, 5]
But when assigning to slices, array remains the same:
>>> a = [0, 1, 2, 3, 4, 5]
>>> b = a
>>> a[:] = ['z']
>>> a
['z']
>>> b
['z']
As you can see, a and b change at the same time, because when assigning to slice, you don't change object's identity, you only change its contents.
>>> a = [0, 1, 2, 3, 4, 5]
>>> b = a
>>> a = ['z']
>>> a
['z']
>>> b
[0, 1, 2, 3, 4, 5]
This is not the case when you just assign to variable, dropping older array out of scope.
def call(nums):
nums = [x for x in nums if x != 4]
Would only change the value of the name nums function parameter which would accomplish nothing.
def call(nums):
nums[:] = [x for x in nums if x != 4]
Changes the actual value of the list passed in as an argument.
I need to write a Prolog predicate which calculate the sum of 2 binary numbers represented in list.
The lists are already reversed, for example ([0,1] base 2) = (2 base 10).
It should work with mode binary_plus(+,+,-), for example
?- binary_plus([1,1],[1],X).
X = [0,0,1].
and with mode binary_plus(-,-,+), for example
?- binary_plus(X,X,[0,1]).
X = [1].
Im not allowed using cut sign,findall,negation,or if-then-else.
Here is my code:
is_binary([]).
is_binary([X]):- X is 1.
is_binary([X|Xs]):-
append(_,[1],Xs),
member(X,[0,1]),
is_binary(Xs).
binary_plus([],X,X):-
is_binary(X).
binary_plus(X,[],X):-
is_binary(X).
binary_plus([0|Xs],[Y|Ys],[Y|Zs]):-
binary_plus(Xs,Ys,Zs).
binary_plus([1|Xs],[0|Ys],[1|Zs]):-
binary_plus(Xs,Ys,Zs).
binary_plus([1|Xs],[1|Ys],[0|Zs]):-
binary_plus(Xs,[1],Ws),
binary_plus(Ws,Ys,Zs).
I dont know where i'm wrong because there are some strange issues that i cant solve,
so if someone could help me i would appreciate it.
Thanks.
When describing lists, always consider using DCG notation. For example, in your case, consider writing this as:
:- use_module(library(clpfd)).
binary_addition(Xs, Ys, As) :-
phrase(binary_addition_(Xs, Ys, 0), As).
binary_addition_([], [], 0) --> [].
binary_addition_([], [], 1) --> [1].
binary_addition_([X|Xs], [], C) --> binary_addition_([X|Xs], [C], 0).
binary_addition_([], [Y|Ys], C) --> binary_addition_([C], [Y|Ys], 0).
binary_addition_([X|Xs], [Y|Ys], C0) -->
{ [X,Y] ins 0..1,
Sum #= X + Y + C0 },
sum_carry(Sum, C),
binary_addition_(Xs, Ys, C).
sum_carry(0, 0) --> [0].
sum_carry(1, 0) --> [1].
sum_carry(2, 1) --> [0].
Example queries and their solutions:
?- binary_addition([1,0],[0,1,1], Sum).
Sum = [1, 1, 1] .
?- binary_addition([1,1],[1,0,1], Sum).
Sum = [0, 0, 0, 1] .
?- binary_addition([0,1],[1,1], Sum).
Sum = [1, 0, 1] .
Notice that it also works in the other direction:
?- binary_addition(Xs, Ys, [1,1]).
Xs = [1, 1],
Ys = [] ;
Xs = [],
Ys = [1, 1] ;
Xs = [_G2510, 1],
Ys = [_G2522],
_G2510 in 0..1,
_G2510+_G2522#=1,
_G2522 in 0..1 ;
etc.
You can simply add a reverse/2 goal to binary_addition/3 if you want the reverse list.
Here my take on binary-addition-without-anything. I understand that you are not to use clpfd:
binary_plus(A,B,C) :- binary_plus_0(A,B,C).
binary_plus_0([], [], []).
binary_plus_0([], [B|Bs],[B|Bs]).
binary_plus_0([A|As],[], [A|As]).
binary_plus_0([A|As],[B|Bs],[C|Cs]) :- binary_plus_0(A,B,C,As,Bs,Cs).
binary_plus_0(0,0,0,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(0,1,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(1,0,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_0(1,1,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1([], [], [1]).
binary_plus_1([], [B|Bs],Cs) :- binary_plus_0([1],[B|Bs],Cs).
binary_plus_1([A|As],[], Cs) :- binary_plus_0([A|As],[1],Cs).
binary_plus_1([A|As],[B|Bs],[C|Cs]) :- binary_plus_1(A,B,C,As,Bs,Cs).
binary_plus_1(0,0,1,As,Bs,Cs) :- binary_plus_0(As,Bs,Cs).
binary_plus_1(0,1,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1(1,0,0,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
binary_plus_1(1,1,1,As,Bs,Cs) :- binary_plus_1(As,Bs,Cs).
__global__
void transpose(double *input, double *output, int *width, int *height)
{
int threadidx = (blockIdx.x * blockDim.x) + threadIdx.x;
int row = threadidx / (*width);
int column = (threadidx+3) % (*height);
output[column * (*height) + row] = input[threadidx];
}
Above is my kernel for linear transformations. For an input matrix of [0, 1, 2, 3, 4, 5, 6, 7, 8] the output matrix should be [0, 3, 6, 1, 4, 7, 2, 5, 8], but when I run this code using the aforementioned example, the output is [0, 3, 6, 0, 0, 0, 0, 0, 0]. I've written a serial implementation of the algorithm in Python, and it works. The only thing I can think of is some sort of thread memory access problem. Any help? Thanks.
As the comments have already pointed out, your code happens to work correctly for the sample input case you have identified:
[0, 1, 2, 3, 4, 5, 6, 7, 8]
And if you are not getting the results you have indicated, then the error is outside of the code you have shown. However, it appears you are trying to transpose an array.
This code will not work for the general case (e.g. try a 2x2 array: [0, 1, 2, 3])
This line of code in particular isn't right, if your intention is to transpose an array:
int column = (threadidx+3) % (*height);
If you change it to:
int column = (threadidx) % (*width);
Your code will produce a correct transpose result for various matrix sizes.