What is the equivalent of this DOFOR pseudocode in MATLAB? - matlab

I was following the following pseudocode from my textbook, and I was able to succesfully implement the function on the left in MATLAB. Now I am working on the function to the right, and I don't understand the following DOFOR line.
On the left, I implemented for i = 1 : n-1, but on the right.. What should the following 2 after n-2 represent?
Well, I ignored the second 2 and just ran my code as i=1:n-2 and I have an incorrect answer. ((The effected answer would be D, ignore et for now. That is a different equation.))
I've highlighted my solution versus the correct solution above:

without knowing the book or the syntax this author is using we can only rely on our knowledge of the simpson's rule.
the simpson's rule is applied on each two consecutive points, so it is likely that the author's DOFOR roughly translates as following.
DOFOR i = start,stop,step
END DO
for i = start:step:stop
end
hence in your code, this would be the right translation.
for i = 1:2:n-2
...
end

Related

Clingo: Operation undefined while doing computations inside the testing rules

I am new to ASP programming and finding it a bit hard to understand how ASP works. I am using clingo tool for ASP coding. Currently, I am working on a seating arrangement problem. The original problem is a bit complicated as it involves lots of variables and constraints. I have started with a basic version of it which is as follows:
4 persons need to be seated in a horizontal row having 4 seats. There are no constraints among these persons. Each person can move left/right to any other person. The final goal is straightforward
"any person can sit at any location provided it is available"
The only condition is to save the individual steps about how the goal is reached.
To solve it, I have used a predicate
seated(A,B,Shift,Dir,t) which says that at time t A has shifted Shift units in the Dir from B
Example
seated(A,B,left,2,t) implies A has shifted 2 units to the left of B at time t
I have used two files
init.lp describing the initial positions and final goal
person(a).
person(b).
person(c).
person(d).
init(pos(a,0)).
init(pos(b,0)).
init(pos(c,0)).
init(pos(d,0)).
goal(pos(a,1)).
goal(pos(b,2)).
goal(pos(c,3)).
goal(pos(d,4)).
rules.lp where the rules are written
#include<incmode>.
#program base.
% Define
holds(F,0) :- init(F).
%{possible_location(X,Y,1) : person(X),Y = 1..4}.
%%possible_location(X,Y,1) : person(X),Y = 1..4.
#program step(t).
% Generate any seating arrangement
1 { seated(X,Z,Shift,Dir,t) : person(X), person(Z), X != Z,Shift = 1..3, Dir = (left;right) } 1.
% Test
% Remove the seated predicates which the shift is not possible
:- seated(X,Z,Shift,right,t), holds(pos(Z,Pos),t-1), Shift + Pos > 4.
:- seated(X,Z,Shift,left,t), holds(pos(Z,Pos),t-1), Pos - Shift < 1.
% Remove the seated predicates if the final position after shifting is already occupied
:- seated(X,Z,Shift,right,t), holds(pos(Z,Pos),t-1), Pos>0, holds(pos(A,Shift + Pos),t-1), A!=X.
:- seated(X,Z,Shift,left,t), holds(pos(Z,Pos1),t-1), Pos1>0, holds(pos(A,Pos1 - Shift),t-1), A!=X.
% Define
seateded(X,t) :- seated(X,Z,Shift,Dir,t).
% Relating the current move to the current state %
holds(pos(X,Y),t) :- seated(X,Y,Shift,Dir,t).
% This is for shifting the state to the next time %
holds(pos(X,Z),t) :- holds(pos(X,Z),t-1), not seateded(X,t).
#program check(t).
% Test
:- query(t), goal(F), not holds(F,t).
% Display
#show seated/5.
#show query/1.
On running the above files, it gives an error
rule_new.lp:21:75-87: info: operation undefined:
(Pos1-Shift)
I have googled it and found out that this error comes when I have not handled any edge case such as X/Y and Y=0 is not handled. In this case, I don't see any edge case. Hence, I am not able to rectify the error.
I have documented the rules so that I can explain the thought process behind writing the rules. I have spent a couple of hours solving it and still couldn't figure out the solution. If my thinking is not in the right direction then I would appreciate if I can get some other solution to the above problem.
I'm afraid I didn't manage to understand your solution (or problem), but using the option --text can help you figure this error out.
According to the error message the problem is in this rule:
seated(X,Z,Shift,left,t),holds(pos(Z,Pos1),t-1), Pos1 >0, holds(pos(A,Pos1 - Shift),t-1), A !=X.
You try to subtract Shift from Pos1. Both Variables should be substituted by integers to make this work.
Shift comes from the seated predicate and can take a value between 1..3, fine.
Pos1 comes from the holds(pos(_,Pos1),_) predicate.
In your rule:
holds(pos(X,Y),t) :- seated(X,Y,Shift,Dir,t).
You clearly derive holds predicates where Y is a person, aka. a, b, c, or d.
So you try to compute 3-a which clingo refuses to do and drops the according rule, raising this warning.

Creating functions in Matlab

Hi, I am trying to write a function as per the question. I have tried to create four sub-matrices which are the reverse of each other and then multiply to give the products demanded by the question. My attempt:
function T = custom_blocksT(n,m)
T(1:end,end-1:1);
T(1:end,end:-1:1)*2;
T(1:end,end:-1:1)*3;
T(1:end,end:-1:1)*4;
What I'm unsure of is
(i) What do the the indivual sub-matrices(T(1:end,end-1:1);)need to be equal to? I was thinking of(1:3)?
(ii) I tried to create a generic sub-matrix which can take any size matrix input using end was this correct or can't you do that? I keep getting this error
Undefined function or variable 'T'.
Error in custom_blocksT (line 2)
T(1:end,end-1:1);
I have searched the Matlab documentation and stacked overflow, but the problem is I'm not quite sure what I'm supposed to be looking for in terms of solving this question.
If someone could help me I would be very thankfull.
There are many problems with your function:
function T = custom_blocksT(n,m)
T(1:end,end-1:1);
T(1:end,end:-1:1)*2;
T(1:end,end:-1:1)*3;
T(1:end,end:-1:1)*4;
end
This is an extremely basic question, I highly recommend you find and work through some very basic MATLAB tutorials before continuing, even before reading this answer to be honest.
That said here is what you should have done and a bit of what you did wrong:
First, you are getting the error that T dos not exist because it doesn't. The only variables that exist in your function are those that you create in the function or those that are passed in as parameters. You should have passed in T as a parameter, but instead you passed in n and m which you don't use.
In the question, they call the function using the example:
custom_blocks([1:3;3:-1:1])
So you can see that they are only passing in one variable, your function takes two and that's already a problem. The one variable is the matrix, not it's dimensions. And the matrix they are passing in is [1:3;3:-1:1] which if you type in the command line you will see gives you
[1 2 3
3 2 1]
So for your first line to take in one argument which is that matrix it should rather read
function TOut = custom_blocks(TIn)
Now what they are asking you to do is create a matrix, TOut, which is just different multiples of TIn concatenated.
What you've done with say TIn(1:end,end-1:1)*2; is just ask MATLAB to multiple TIn by 2 (that's the only correct bit) but then do nothing with it. Furthermore, indexing the rows by 1:end will do what you want (i.e. request all the rows) but in MATLAB you can actually just use : for that. Indexing the columns by end-1:1 will also call all the columns, but in reverse order. So in effect you are flipping your matrix left-to-right which I'm sure is not what you wanted. So you could have just written TIn(:,:) but since that's just requesting the entire matrix unchanged you could actually just write TIn.
So now to multiply and concatenate (i.e. stick together) you do this
TOut = [TIn, TIn*2; TIn*3, TIn*4]
The [] is like a concatenate operation where , is for horizontal and ; is for vertical concatenation.
Putting it all together:
function TOut = custom_blocks(TIn)
TOut = [TIn, TIn*2; TIn*3, TIn*4];
end

vectorizing "for" loop with bidirectionally related variables

Last week I asked the following:
https://stackoverflow.com/questions/32658199/vectorizing-gibbs-sampler-in-matlab
Perhaps it was not that clear what I want to do, so this might be more clear.
I would like to vectorize a "for" loop in matlab, where some variables inside of the loop are bidirectionally related. So, here is an example:
A=2;
B=3;
for i=1:10000
A=3*B;
B=exp(A*(-1/2))
end
Thank you once again for your time.
A quick Excel calculation indicates that this quickly converges to 0.483908 (after much less than 10000 loops - so one way of speeding it up would be to check for convergence). If A and B are always 2 and 3 respectively, you could just replace the loop with this value.
Alternatively, using some series analysis you might be able to come up with an analytical expression for B when i is large - although with the nested exponents deriving this is a bit beyond my own abilities!
Edit
A bit of googling reveals this. Wikipedia states that for a tetration of x to infinity (i.e. x^x^x^x^x...), the solution y satisfies y = x^y. In your case, for example, 0.483908 = e^(-3/2)^0.483908, so 0.483908 is a solution. Not sure how you would exploit this though.
Wikipedia also gives a convergence condition, which might be of use to you: x lies between e^-e and e^1/e.
Final Edit (?)
Turns out you need Lambert's W function to solve for equations of the form of y = x^y. There seems to be no native function for this, but there seems to be something in the FileExchange - see here and here.

Matlab plot won't return correct results

I have written a function that is the beginning of a Poisson Process
function n_t = PoisProc2(t,tao,SIZE)
n_t=0;
for n=1:SIZE
if t>tao(1,n)
n_t=n_t+1;
end
end
end
tao is simply an array of random doubles of length SIZE. For simplicity we'll say [1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,20]
So this functions purpose is to count how many elements of tao that t is greater than for any given t.
This code works fine when I simply write
PoisProc2(3,tao,20);
the answer I get is 19 as expected, but if I write
x=1:.01:20;
y=PoisProc2(x,tao,20);
plot(x,y,'-')
y shows up as 0 in the workspace (I would expect an array of length 1901) and my plot also reads 0. I'm pretty new to Matlab, but this seems like a pretty simply thing I'm trying to do and I must be missing something obvious. Please help!
Your code does not work as you are giving a vector. So your if condition is not working as you expect.
First initialize n_t with a vector :
n_t=zeros(1,length(t))
instead of
if t>tao(1,n)
n_t=n_t+1;
end
Vectorize your expression :
n_t = n_t + (t>tao(1,n))
Cheers
Because x is a vector in your last example, the "if t>tao(1,n)" statement in your function behave totally different from what you think.
This function below should give you the right result.
function ret = PoisProc2(thresholds, vec)
ret = zeros(size(thresholds));
for k = 1:numel(thresholds)
ret(k) = numel(nonzeros(vec > thresholds(k)));
end
Side comments:
Your original function is quite C/Java style. You can see in my function, it's replaced by a one-liner "numel(nonzeros(vec > thresholds(k)))", which is more MATLAB style.
I think this can be done with hist() function. But this probably is easier to understand.

How to sort in ascending order the solution vector in each iteration using ODE?

I've got an ODE system working perfectly. But now, I want in each iteration, sort in ascending order the solution vector. I've tried many ways but I could not do it. Does anyone know how to do?
Here is a simplified code:
function dtemp = tanque1(t,temp)
for i=1:N
if i==1
dtemp(i)=(((-k(i)*At*(temp(i)-temp(i+1)))/(y))-(U*As(i)*(temp(i)-Tamb)))/(ro(i)*vol_nodo*cp(i));
end
if i>1 && i<N
dtemp(i)=(((k(i)*At*(temp(i-1)-temp(i)))/(y))-((k(i)*At*(temp(i)-temp(i+1)))/(y))-(U*As(i)*(temp(i)-Tamb)))/(ro(i)*vol_nodo*cp(i));
end
if i==N
dtemp(i)=(((k(i)*At*(temp(i-1)-temp(i)))/(y))-(U*As(i)*(temp(i)-Tamb)))/(ro(i)*vol_nodo*cp(i));
end
end
end
Test Script:
inicial=343.15*ones(200,1);
[t temp]=ode45(#tanque1,0:360:18000,inicial);
It looks like you have three different sets of differential equations depending on the index i of the solution vector. I don't think you mean "sort," but rather a more efficient way to implement what you've already done - basically vectorization. Provided I haven't accidentally made any typos (you should check), the following should do what you need:
function dtemp = tanque1(t,temp)
dtemp(1) = (-k(1)*At*(temp(1)-temp(2))/y-U*As(1)*(temp(1)-Tamb))/(ro(1)*vol_nodo*cp(1));
dtemp(2:N-1) = (k(2:N-1).*(diff(temp(1:N-1))-diff(temp(2:N)))*At/y-U*As(2:N-1).*(temp(2:N-1)-Tamb))./(vol_nodo*ro(2:N-1).*cp(2:N-1));
dtemp(N) = (k(N)*At*(temp(N-1)-temp(N))/y-U*As(N)*(temp(N)-Tamb))/(ro(N)*vol_nodo*cp(N));
You'll still need to define N and the other parameters and ensure that temp is returned as a column vector. You could also try replacing N with the end keyword, which might be faster. The two uses of diff make the code shorter, but, depending on the value of N, they may also speed up the calculation. They could be replaced with temp(1:N-2)-temp(2:N-1) and temp(2:N-1)-temp(3:N). It may be possible to collapse these down to a single vectorized equation, but I'll leave that as an exercise for you to attempt if you like.
Note that I also removed a great many unnecessary parentheses for clarity. As you learn Matlab you'll to get used to the order of operations and figure out when parentheses are needed.