How to remove repetitions using retract in this particular situation? - database

%Examples:
%days([saturday,sunday,monday,tuesday,wednesday,thursday]).
%slots([1,2,3,4,5]).
%course_meetings(csen402,tutorial,t07,nehal,'tutorial for t07').
%course_meetings(comm401,lecture,all_group_4,dr_amr_talaat,'lecture 1')
%tutorialrooms([c6301,b4108,c2201,c2301,c2202,c2203]).
day_tut(Day,Slot,Place,Course,Group,Instructor,Descr):-
days(X),member(Day,X),
tutorialrooms(X1),member(Place,X1),
course_meetings(Course,tutorial,Group,Instructor,Descr),
slots(X2),member(Slot,X2),
assert(day(Day,Slot,tutorial,Place,Course,Group,Instructor,Descr)).
I would like to find a way to remove certain facts after asserting for example
every (day) fact has to have only one room for each day and slot
example: we can have day(sat,1,_,c6301,_,_,_,_) and
day(sat,1,_,c6302,_,_,_,_) but we can't have
another occurrence of day(sat,1,_,c6301,_,_,_,_).

If you simply want to remove redundant solutions of a Goal – this is what you probably mean with removing repetitions – simply replace Goal by setof(t,Goal,_). This works as long as there are only ground solutions for Goal and as long as Goal terminates universally. Thus, there is no need for any data base manipulation to remove redundant solutions.
?- member(X, [a,b,a,c]).
X = a
; X = b
; X = a % redundant!
; X = c.
?- setof(t,member(X, [a,b,a,c]),_).
X = a
; X = b
; X = c.

Related

Initiate for loop

I have the following question:
I am building a model when I first test for stationarity. Then I have an if loop, saying:
if p>0.05:
x=y['boxcox']
else:
x=y['Normal']
If the pvalue is bigger than 0.05, then I do the boxcox transformation, if not, then I use my original values. This works.
I then have a large code, that is working.
However, in the end, I want to transform my values back.
Again with the if loop.
But how do I get the if loop started?
I first wanted to do:
if any (x==y['BoxCox']):
.....transform back
This works if I orginially have transformed my values, but not if I didn't, which makes sense, because the code does not know y['BoxCox'].
But how do I get the if loop initiated?
Thanks a lot!
If I understand your question correctly, you do not transform anything back, rather you remember the initial state. "Transforming back" sounds like a potential source of bugs. What if you alter your transformation algorithm and forget to update the transforming back part?
here is a simplified example, to illustrate my understanding of your problem:
x = 4
if x > 2:
x = x + 1
else:
x = x + 100
print("Result = ", x)
print("Initial value was ???") // you cannot tell what was the initial x
You can simply do not touch the initial values, to be accessible at any time:
x = 4
if x > 2:
result = x + 1
else:
result = x + 100
print("Result = ", result)
print("Initial value = , x)

MATLAB solve array

I've got multiple arrays that you can't quite fit a curve/equation to, but i do need to solve them for a lot of values. Simplified it looks like this when i plot it, but the real ones have a lot more points:
So say i would like to solve for y=22,how would i do that? As you can see there'd be three solutions to this, but i only need the most left one.
Linear is okay, but i'd rather us a non-linear method.
The only way i found is to fit an equation to a set of points and solve that equation, but an equation can't approximate the array accurately enough.
This implementation uses a first-order interpolation- if you're looking for higher accuracy and it feels appropriate, you can use a similar strategy for another order estimator.
Assuming data is the name of your array containing data with x values in the first column and y values in the second, that the columns are sorted by increasing or decreasing x values, and you wanted to find all data at the value y = 22;
searchPoint = 22; %search for all solutions where y = 22
matchPoints = []; %matrix containing all values of x
for ii = 1:length(data)-1
if (data(ii,2)>searchPoint)&&(data(ii+1,2)<searchPoint)
xMatch = data(ii,1)+(searchPoint-data(ii,2))*(data(ii+1,1)-data(ii,1))/(data(ii+1,2)-data(ii,2)); %Linear interpolation to solve for xMatch
matchPoints = [matchPoints xMatch];
elseif (data(ii,2)<searchPoint)&&(data(ii+1,2)>searchPoint)
xMatch = data(ii,1)+(searchPoint-data(ii,2))*(data(ii+1,1)-data(ii,1))/(data(ii+1,2)-data(ii,2)); %Linear interpolation to solve for xMatch
matchPoints = [matchPoints xMatch];
elseif (data(ii,2)==searchPoint) %check if data(ii,2) is equal
matchPoints = [matchPoints data(ii,1)];
end
end
if(data(end,2)==searchPoint) %Since ii only goes to the rest of the data
matchPoints = [matchPoints data(end,1)];
end
This was written sans-compiler, but the logic was tested in octave (in other words, sorry if there's a slight typo in variable names, but the math should be correct)

How to transform multiple similar outputs into a single output array?

I have two issues that I desperately need help with, so I'm posting here.
I know this may sound like a much-asked question at first, but I didn't find anything like it in my research.
I'm trying to obtain an entire row of results, using this code:
mu = [0 0];
sigma = [1 0.3; 0.3 1];
for r1 = 1:7;
r2 = 1;
xu = [r1+1, r2+1];
xl = [r1, r2];
p1 = mvncdf(xl,xu,mu,sigma)
end
What I am trying to say is that, for every value that r1 takes (between 1 and 7), r2 will assume the value 1, and I want to generate the values for those 7 combinations. When I run the scripts, I get excatly the values that I want, but in this form:
p1 =
0.0301
p1 =
0.0062
p1 =
4.5904e-04
p1 =
1.2186e-05
p1 =
1.1389e-07
p1 =
3.7054e-10
p1 =
4.1622e-13
After that, when I go to my workspace, I have a variable there named p1, but is only equal to the last value generated - in this case, 4.1622e-13. Is it possible to make this generate an array with all the 7 numbers instead?
My second question is related to this one. As you saw, I use r1 ranging from 1 to 7, and r2 takes the value of 1. Truth is, I want to assess all combinations of them, with r2 also ranging from 1 to 7, but I'm doing it manually, with 7 other similar pieces of code, each one for a value of r2. Is it possible to combine everything and code it in a way that it generates a matrix of values based on all the combinations? I understand that might be more difficult, and I am more concerned with the first question.
For you first question, you want to create a vector of p1 values, so just modify your code like this:
p1(r1) = mvncdf(xl,xu,mu,sigma)
which when r1=1, the first time you loop, will put the result into the first element of p1 and so on.
For the second part of your question, you can nest another for loop, as follows:
for r1 = 1:7;
for r2 = 1:7;
xu = [r1+1, r2+1];
xl = [r1, r2];
p1(r1,r2) = mvncdf(xl,xu,mu,sigma)
end
end
and now you will have a matrix p1 where, for example, the entry in the (4,6) position corresponds to r1=4 and r2=6.
It is possible to compress this,
r1=1:7;
r2=1:7;
[R1,R2]=meshgrid(r1,r2);
p1=arrayfun(#(r1,r2) mvncdf([r1 r2],[r1+1 r2+1],mu,sigma),R1,R2)
but there is no real need to do so.

Dynamically creating and naming an array

Consider the following code snippet
for i = 1:100
Yi= x(i:i + 3); % i in Yi is not an index but subscript,
% x is some array having sufficient values
i = i + 3
end
Basically I want that each time the for loop runs the subscript changes from 1 to 2, 3, ..., 100. SO in effect after 100 iterations I will be having 100 arrays, starting with Y1 to Y100.
What could be the simplest way to implement this in MATLAB?
UPDATE
This is to be run 15 times
Y1 = 64;
fft_x = 2 * abs(Y1(5));
For simplicity I have taken constant inputs.
Now I am trying to use cell based on Marc's answer:
Y1 = cell(15,1);
fft_x = cell(15,1);
for i = 1:15
Y1{i,1} = 64;
fft_x{i,1} = 2 * abs(Y1(5));
end
I think I need to do some changes in abs(). Please suggest.
It is impossible to make variably-named variables in matlab. The common solution is to use a cell array for Y:
Y=cell(100,1);
for i =1:100
Y{i,1}= x(i:i+3);
i=i+3;
end
Note that the line i=i+3 inside the for-loop has no effect. You can just remove it.
Y=cell(100,1);
for i =1:100
Y{i,1}= x(i:i+3);
end
It is possible to make variably-named variables in matlab. If you really want this do something like this:
for i = 1:4:100
eval(['Y', num2str((i+3)/4), '=x(i:i+3);']);
end
How you organize your indexing depends on what you plan to do with x of course...
Yes, you can dynamically name variables. However, it's almost never a good idea and there are much better/safer/faster alternatives, e.g. cell arrays as demonstrated by #Marc Claesen.
Look at the assignin function (and the related eval). You could do what asked for with:
for i = 1:100
assignin('caller',['Y' int2str(i)],rand(1,i))
end
Another related function is genvarname. Don't use these unless you really need them.

Subset Sum TI Basic Programming

I'm trying to program my TI-83 to do a subset sum search. So, given a list of length N, I want to find all lists of given length L, that sum to a given value V.
This is a little bit different than the regular subset sum problem because I am only searching for subsets of given lengths, not all lengths, and recursion is not necessarily the first choice because I can't call the program I'm working in.
I am able to easily accomplish the task with nested loops, but that is becoming cumbersome for values of L greater than 5. I'm trying for dynamic solutions, but am not getting anywhere.
Really, at this point, I am just trying to get the list references correct, so that's what I'm looking at. Let's go with an example:
L1={p,q,r,s,t,u}
so
N=6
let's look for all subsets of length 3 to keep it relatively short, so L = 3 (6c3 = 20 total outputs).
Ideally the list references that would be searched are:
{1,2,3}
{1,2,4}
{1,2,5}
{1,2,6}
{1,3,4}
{1,3,5}
{1,3,6}
{1,4,5}
{1,4,6}
{1,5,6}
{2,3,4}
{2,3,5}
{2,3,6}
{2,4,5}
{2,4,6}
{2,5,6}
{3,4,5}
{3,4,6}
{3,5,6}
{4,5,6}
Obviously accomplished by:
FOR A,1,N-2
FOR B,A+1,N-1
FOR C,B+1,N
display {A,B,C}
END
END
END
I initially sort the data of N descending which allows me to search for criteria that shorten the search, and using FOR loops screws it up a little at different places when I increment the values of A, B and C within the loops.
I am also looking for better dynamic solutions. I've done some research on the web, but I can't seem to adapt what is out there to my particular situation.
Any help would be appreciated. I am trying to keep it brief enough as to not write a novel but explain what I am trying to get at. I can provide more details as needed.
For optimisation, you simply want to skip those sub-trees of the search where you already now they'll exceed the value V. Recursion is the way to go but, since you've already ruled that out, you're going to be best off setting an upper limit on the allowed depths.
I'd go for something like this (for a depth of 3):
N is the total number of array elements.
L is the desired length (3).
V is the desired sum
Y[] is the array
Z is the total
Z = 0
IF Z <= V
FOR A,1,N-L
Z = Z + Y[A]
IF Z <= V
FOR B,A+1,N-L+1
Z = Z + Y[B]
IF Z <= V
FOR C,B+1,N-L+2
Z = Z + Y[C]
IF Z = V
DISPLAY {A,B,C}
END
Z = Z - Y[C]
END
END
Z = Z - Y[B]
END
END
Z = Z - Y[A]
END
END
Now that's pretty convoluted but it basically check at every stage whether you've already exceed the desired value and refuses to check lower sub-trees as an efficiency measure. It also keeps a running total for the current level so that it doesn't have to do a large number of additions when checking at lower levels. That's the adding and subtracting of the array values against Z.
It's going to get even more complicated when you modify it to handle more depth (by using variables from D to K for 11 levels (more if you're willing to move N and L down to W and X or if TI BASIC allows more than one character in a variable name).
The only other non-recursive way I can think of doing that is to use an array of value groups to emulate recursion with iteration, and that will look only slightly less hairy (although the code should be less nested).

Resources