A simple math in Python that's hard for me - function

Please help me. I'm trying to learn Python and I'm very beginner. I tried reading and watching videos but I don't understand this logic:
def myFunction(y):
x = y + y #Local
print(x)
return x
x = 5 #Global
myFunction(x)
print(x)
I get the values 10 and 5.
Really, I can't understand why 10. This is breaking my mind. If x equals 5, than the result of the line 2 shouldn't be 2.5? I have 5 = y + y.
My mind is on a loop. Please help, you're my only hope.

You are passing x as the argument of your function myFunction().
Thus if x=5 you get:
myFunction(5):
x = 5 + 5
return(x) #10
this is why you are getting 10. If you change x=5 to x=10 you will see that the result of the function will be 20 and so on...
You are not replacing the x in the function itself. However, the x you stated will indeed remain a global variable and thus will be printed on the second line.

Related

Removing DC component for matrix in chuncks in octave

I'm new to octave and if this as been asked and answered then I'm sorry but I have no idea what the phrase is for what I'm looking for.
I trying to remove the DC component from a large matrix, but in chunks as I need to do calculations on each chuck.
What I got so far
r = dlmread('test.csv',';',0,0);
x = r(:,2);
y = r(:,3); % we work on the 3rd column
d = 1
while d <= (length(y) - 256)
e = y(d:d+256);
avg = sum(e) / length(e);
k(d:d+256) = e - avg; % this is the part I need help with, how to get the chunk with the right value into the matrix
d += 256;
endwhile
% to check the result I like to see it
plot(x, k, '.');
if I change the line into:
k(d:d+256) = e - 1024;
it works perfectly.
I know there is something like an element-wise operation, but if I use e .- avg I get this:
warning: the '.-' operator was deprecated in version 7
and it still doesn't do what I expect.
I must be missing something, any suggestions?
GNU Octave, version 7.2.0 on Linux(Manjaro).
Never mind the code works as expected.
The result (K) got corrupted because the chosen chunk size was too small for my signal. Changing 256 to 4096 got me a better result.
+ and - are always element-wise. Beware that d:d+256 are 257 elements, not 256. So if then you increment d by 256, you have one overlaying point.

expand log on Octave

I am trying to expand log expression with octave like that:
expand(log(x^2))
to get 2 * log(x)
but that doesn't work
That works with matlab when making:
expand(log(x^2),'IgnoreAnalyticConstraints',true)
but octave doesn't recognise it.
Any idea how to make it with octave?
You need to specify that x is a positive variable first.
pkg load symbolic
x = sym('x', 'positive' );
expand( log( x ^ 2 ) ) % ans = (sym) 2⋅log(x)

Octave - System of differential equations with lsode

here is my problem. I'm trying to solve a system of two differential equations thanks to the two functions below. The part of the code that give me some trouble is the variable "rho". "rho" is a function which values are given from a file and that I tried to put in the the variable rho.
function [xdot]=f2(x,t)
# Parameters of the equations
t=[1:1:35926];
x = dlmread('data_txt.txt');
rho=x(:,4);
beta = 0.68*10^-2;
g = 1.5;
l = 1.6;
# Definition of the system of 2 ODE's :
xdot(1) = ((rho-beta)/g)*x(1) + l*x(2);
xdot(2) = (beta/g)*x(1)-l*x(2);
endfunction
.
# Initial conditions for the two variables :
x0 = [0;1];
# Definition of the time-vector -> (initial time,temporal mesh,final time) :
t = linspace (1, 10, 10000);
# Resolution with the lsode routine :
x = lsode ("f2", x0, t);
# Plot of the two curves :
plot (t,x);
When I run my code, I get the following error:
>> resolution_effective2
error: f2: A(I) = X: X must have the same size as I
error: called from
f2 at line 34 column 9
resolution_effective2 at line 8 column 3
error: lsode: evaluation of user-supplied function failed
error: called from
resolution_effective2 at line 8 column 3
error: lsode: inconsistent sizes for state and derivative vectors
error: called from
resolution_effective2 at line 8 column 3
I know that my error comes from a mismatch of size between some variable but I have been looking for the error for days now and I don't see. Could someone try to give and explain me an effective correction ?
Thank you
The error might come from your function f2. Its first argument x should have the same dimension as x0 since x0 is the initial condition of x.
In your case, whatever you intent to be the first argument of f2 is ignored since in your function you do x = dlmread('data_txt.txt'); this seems to be a mistake.
Then, xdot(1) = ((rho-beta)/g)*x(1) + l*x(2); will be a problem since rho is a vector.
You need to check the dimensions of x and rho.

GNUPLOT : Plotting a user defined equations which operates indifferent intervals

Hi there I need some help!
I am new to Gnuplot and have difficulties with the scripts.
Actually my equation is a lot more complicated. It is a parametric equation consisting of 7 parts each defined into a specific interval, with a bunch of parameters.
I just need a lead. So let me simplify the problem.
Suppose I have a function defined as follows f(x)= a*x+cos(x) : for 0 <= x <= 3;
and f(x)= b*1/cos(x) : for 3 < x <=10
my question is how do I instruct GNUPLOT:
1-) to consider "a" and "b" as parameters
2-) to plot "my user-defined" equation into the intervals of definition of f(x)
So far I have used the "set parametric" command but the problem is always at the end at the "PLOT f(x)" command for which I really don't know how to deal with the intervals.
I am using Windows 7 with the latest gnuplot.
Please help
You can define your f(x) as a (conditional) piece-wise function:
f(x) = 0 <= x && x <= 3 ? a*x+cos(x) : 3 < x && x <= 10 ? b/cos(x) : 1/0
The 1/0 above makes sure the function is not defined outside of the given intervals. The parameters a and b are already implicitly treated as parameters by gnuplot. When you change their values, f(x) is updated automatically. Example:
set xrange [-2:12]
a = 1.; b = 1.
plot f(x)
If you want more flexibility, you can take a and b as variables and do the following:
f(x,a,b) = 0 <= x && x <= 3 ? a*x+cos(x) : 3 < x && x <= 10 ? b/cos(x) : 1/0
set xrange [-2:12]
plot f(x,1,1), f(x,2,3)

Using arrayfun to apply two arguments of a function on every combination

Let i = [1 2] and j = [3 5]. Now in octave:
arrayfun(#(x,y) x+y,i,j)
we get [4 7]. But I want to apply the function on the combinations of i vs. j to get [i(1)+j(1) i(1)+j(2) i(2)+j(1) i(2)+j(2)]=[4 6 5 7].
How do I accomplish this? I know I can go with for-loopsl but I want vectorized-code because it's faster.
In Octave, for finding summations between two vectors, you can use a truly vectorized approach with broadcasting like so -
out = reshape(ii(:).' + jj(:),[],1)
Here's a runtime test on ideone for the input vectors of size 1 x 100 each -
-------------------- With FOR-LOOP
Elapsed time is 0.148444 seconds.
-------------------- With BROADCASTING
Elapsed time is 0.00038299 seconds.
If you want to keep it generic to accommodate operations other than just summations, you can use anonymous functions like so -
func1 = #(I,J) I+J;
out = reshape(func1(ii,jj.'),1,[])
In MATLAB, you could accomplish the same with two bsxfun alternatives as listed next.
I. bsxfun with Anonymous Function -
func1 = #(I,J) I+J;
out = reshape(bsxfun(func1,ii(:).',jj(:)),1,[]);
II. bsxfun with Built-in #plus -
out = reshape(bsxfun(#plus,ii(:).',jj(:)),1,[]);
With the input vectors of size 1 x 10000 each, the runtimes at my end were -
-------------------- With FOR-LOOP
Elapsed time is 1.193941 seconds.
-------------------- With BSXFUN ANONYMOUS
Elapsed time is 0.252825 seconds.
-------------------- With BSXFUN BUILTIN
Elapsed time is 0.215066 seconds.
First, your first example is not the best because the most efficient way to accomplish what you're doing with arrayfun would be to vectorize:
a = [1 2];
b = [3 5];
out = a+b
Second, in Matlab at least, arrayfun is not necessarily faster than a simple for loop. arrayfun is mainly a convenience (especially for it's more advanced options). Try this simple timing example yourself:
a = 1:1e5;
b = a+1;
y = arrayfun(#(x,y)x+y,a,b); % Warm up
tic
y = arrayfun(#(x,y)x+y,a,b);
toc
y = zeros(1,numel(a));
for k = 1:numel(a)
y(k) = a(k)+b(k); % Warm up
end
tic
y = zeros(1,numel(a));
for k = 1:numel(a)
y(k) = a(k)+b(k);
end
toc
In Matlab R2015a, the for loop method is over 70 times faster run from the Command window and over 260 times faster when run from an M-file function. Octave may be different, but you should experiment.
Finally, you can accomplish what you want using meshgrid:
a = [1 2];
b = [3 5];
[x,y] = meshgrid(a,b);
out = x(:).'+y(:).'
which returns [4 6 5 7] as in your question. You can also use ndgrid to get output in a different order.