Matlab Operators - matlab

I am studying for cumulative exam I have tomorrow and I got the following question wrong on a previous exam. I was hoping someone could explain this question to me? What does (~m) mean?
The question says:
After executing the following script, what is the value of m?
a=1; b=2; m=0;
if (~m)
m = m+1;
if (a-b > 0)
m = m+1;
else
m = m -1;
end
elseif (m > 1)
m = m + 2;
else
m = m - 2;
end
The correct answer is 0, but why? I would have guessed that m = -2

The ~ means NOT. However, numeric values are all considered TRUE unless they are identically equal to 0.
So, the commands which are actually executed by this logic are:
m = m+1; %Following if (~m)
m = m-1; $Following else
Also, there is a nested if statement in the code. It will be easier to read if you used multiple level indentations.

Related

Infeasible for simple binary matrix using cplex and yalmip

I'm getting start with cplex and yalmip. I got a 'Integer infeasible column 'x2'.' for the code below.
N = 2;
O = binvar(N,N);
F = [];
for i = 1:N
for j = 1:N
if i ==j
F = F + (O(i,i) ==0);
else
F = F+ (O(i,j) + O(j,i) ==1);
end
end
end
optimize(F);
diagnostics = optimize(F);
if diagnostics.problem == 0
disp('Feasible');
elseif diagnostics.problem == 1
disp('Infeasible');
else
disp('Something else happened');
disp(diagnostics.problem);
end
I'm not sure what's wrong here.... The constraints looks quite feasible to me?
Square matrices are symmetric by default, hence your model is infeasible
https://yalmip.github.io/tutorial/basics/
YALMIP-specific questions are much better addressed on YALMIP specific forums
https://github.com/yalmip/YALMIP/discussions
https://groups.google.com/forum/?fromgroups=#!forum/yalmip

Replacing a for loop with a while loop

I have written a function that estimates the inverse of e and loops through values of n until the approximated value is within a given tolerance of the actual value.
Currently I use this code:
function [approx, n] = calc_e(tolerance)
for n = 1:inf
approx = ((1-1/n)^n);
diff = (1/exp(1)) - approx;
if diff < tolerance, break; end
end
end
This works fine however I have been told that it could be more efficient by using a while loop but I can't work out how to do it in that way.
Can anybody shed some light on this?
Simply do:
function [approx, n] = calc_e(tolerance)
n = 1;
while (1/exp(1)) - ((1-1/n)^n) >= tolerance
n = n + 1;
end
end

Plotting own function in scilab

Hey i have an issuse with plotting my own function in scilab.
I want to plot the following function
function f = test(n)
if n < 0 then
f(n) = 0;
elseif n <= 1 & n >= 0 then
f(n) = sin((%pi * n)/2);
else
f(n) = 1;
end
endfunction
followed by the the console command
x = [-2:0.1:2];
plot(x, test(x));
i loaded the function and get the following error
!--error 21
Invalid Index.
at line 7 of function lala called by :
plot(x, test(x))
Can you please tell me how i can fix this
So i now did it with a for loop. I don't think it is the best solution but i can't get the other ones running atm...
function f = test(n)
f = zeros(size(n));
t = length(n);
for i = 1:t
if n(i) < 0 then
f(i) = 0;
elseif n(i) <= 1 & n(i) >= 0
f(i) = sin((%pi * n(i)/2));
elseif n(i) > 1 then
f(i) = 1;
end
end
endfunction
I guess i need to find a source about this issue and get used with the features and perks matlab/scilab have to over :)
Thanks for the help tho
The original sin is
function f = test(n)
(...)
f(n) = (...)
(...)
endfunction
f is supposed to be the result of the function. Therefore, f(n) is not "the value that the function test takes on argument n", but "the n-th element of f". Scilab then handles this however it can; on your test case, it tries to access a non-integer index, which results in an error. Your loop solution solves the problem.
Replacing all three f(n) by f in your first formulation makes it into something that works... as long as the argument is a scalar (not an array).
If you want test to be able to accept vector arguments without making a loop, the problem is that n < 0 is a vector of the same size as n. My solution would use logical arrays for indexing each of the three conditions:
function f = test(n)
f = zeros(size(n));
negative = (n<0);//parentheses are optional, but I like them for readability
greater_than_1 = (n>1);
others = ~negative & ~greater_than_1;
f(isnegative)=0;
f(greater_than_1)=1;
f(others) = sin(%pi/2*n(others));
endfunction

matlab parcial equation with 2 intervals

Here is the code I have so far :
function [u]=example222(xrange,trange,uinit,u0bound,uLbound);
n = length(xrange);
m = length(trange);
u = zeros(n,m); %%%
Dx = (xrange(n)-xrange(1))/(n-1);
Dt = (trange(m)-trange(1))/(m-1);
u(:,1)=uinit';
u(1,:)=u0bound;
u(n,:)=uLbound;
gegu=0.08;
alpha=0;
koefa=(-Dt*gegu/(2*Dx));
koefb=(alpha*Dt/(Dx)^2);
u
% first time step
for i = 2:n-1
u(i,2) = u(i,1)+2*koefa*(u(i+1,1)-u(i-1,1))+(koefb/2)*(u(i-1,1)-2*u(i,1)+u(i+1,1))
end;
% subsequent time steps
for j = 2:m-1
for i = 2:n-1
u(i,j+1)=u(i,j-1)+koefa*(u(i+1,j)-u(i-1,j))+koefb*(u(i-1,j)-2*u(i,j)+u(i+1,j))
end;
end;
______________________________________
x = (0:0.1:1);
t = (0:0.8:8) ;
u0=zeros;uL=zeros;
uinit=1-(10*x-1).^2;
[u]=example222(x,t,uinit,u0,uL);
surf(x,t,u,'EdgeColor','black')
Next thing I need to do is to implement an interval for uinit=1-(10*x-1).^2
IF x-0.08*t < 0.2. then => uinit=1-(10*x-1).^2;
else uinit=0;
Can someone help me with that please. I was trying to do it with if clauses and loops and couldn't make it work. Help is greatly appreciated.
There are many ways to define a piecewise function my usual method is as follows:
uinit = zeros(size(x));
I = x<(0.08*t+0.2); %// Find the indices where x<(0.08*t+0.2)
uinit(I) = 1-(10*x(I)-1).^2;
This case is easier than what you may often have since you want all the other values of uinit to be zero. If you had another function in the other region (say x^2) you could also do:
uinit(1-I) = x(1-I).^2;
The operation 1-I gives 0 where I==1 and 1 where I==0, therefore your get the complement of I.

optimizing nested for loop in matlab

I'm trying to optimize the performance (e.g. speed) of my code. I 'm new to vectorization and tried myself to vectorize, but unsucessful ( also try bxsfun, parfor, some kind of vectorization, etc ). Can anyone help me optimize this code, and a short description of how to do this?
% for simplify, create dummy data
Z = rand(250,1)
z1 = rand(100,100)
z2 = rand(100,100)
%update missing param on the last updated, thanks #Bas Swinckels and #Daniel R
j = 2;
n = length(Z);
h = 0.4;
tic
[K1, K2] = size(z1);
result = zeros(K1,K2);
for l = 1 : K1
for m = 1: K2
result(l,m) = sum(K_h(h, z1(l,m), Z(j+1:n)).*K_h(h, z2(l,m), Z(1:n-j)));
end
end
result = result ./ (n-j);
toc
The K_h.m function is the boundary kernel and defined as (x is scalar and y can be vector)
function res = K_h(h, x,y)
res = 0;
if ( x >= 0 & x < h)
denominator = integral(#kernelFunc,-x./h,1);
res = 1./h.*kernelFunc((x-y)/h)/denominator;
elseif (x>=h & x <= 1-h)
res = 1./h*kernelFunc((x-y)/h);
elseif (x > 1 - h & x <= 1)
denominator = integral(#kernelFunc,-1,(1-x)./h);
res = 1./h.*kernelFunc((x-y)/h)/denominator;
else
fprintf('x is out of [0,1]');
return;
end
end
It takes a long time to obtain the results: \Elapsed time is 13.616413 seconds.
Thank you. Any comments are welcome.
P/S: Sorry for my lack of English
Some observations: it seems that Z(j+1:n)) and Z(1:n-j) are constant inside the loop, so do the indexing operation before the loop. Next, it seems that the loop is really simple, every result(l, m) depends on z1(l, m) and z2(l, m). This is an ideal case for the use of arrayfun. A solution might look something like this (untested):
tic
% do constant stuff outside of the loop
Zhigh = Z(j+1:n);
Zlow = Z(1:n-j);
result = arrayfun(#(zz1, zz2) sum(K_h(h, zz1, Zhigh).*K_h(h, zz2, Zlow)), z1, z2)
result = result ./ (n-j);
toc
I am not sure if this will be a lot faster, since I guess the running time will not be dominated by the for-loops, but by all the work done inside the K_h function.