How to declare variables in for loop? (IDL) - idl-programming-language

For example,
My files are naming after 00.dat, 01.dat, 02.dat..., each file contains multiple columns and I use READCOL to read them into variables.
for i = 0, n-1 do begin
readcol, string(i, F='(I02)')+'.dat', F='D,D', a0, b0
readcol, string(i, F='(I02)')+'.dat', F='D,D', a1, b1
.
.
c1 = a1 / a0
c2 = a2 / a0
.
.
d1 = b1 / b0
d2 = b2 / b0
.
.
endfor
This works fine, but I cannot type all the varialbes one by one if there will be, say, one hundred variables.
Therefore, I want to use for loop to generate: a(i), b(i), c(i), d(i). In that sense, the code will look like:
for i = 0, n-1 do begin
readcol, string(i, F='(I02)')+'.dat',F='D,D', a(i), b(i)
endfor
for i = 0, n-1 do begin
c(i) = a(i) / a(0)
d(i) = b(i) / b(0)
endfor
But this doesn't work, is there any method to declare variables in a for loop and while doing math?
(I am not a native English speaker. Please let me know If there is anything unclear in my question. Thank you!)

Nice to see another IDL programmer on StackOverflow!
I think part of the problem is that READCOL is expecting simple variable names for
its outputs, and in your second example you're giving it array expressions like
a(i) and b(i) instead of a and b.
If I understand your question correctly, you want to replace the 1-dimensional arrays
a0, a1, b0, b1, etc. from your first example, with 2-dimensional arrays a, b,
etc. where each array has dimensions (nfiles, samples_per_file). So if you know
in advance how many lines will be read from each file, you could do something like this:
a=dblarr(n,samples_per_file)
b=dblarr(n,samples_per_file)
; similarly for c, d, etc.
for i = 0, n-1 do begin
readcol, string(i, F='(I02)')+'.dat',F='D,D', x, y
a[i,*] = x
b[i,*] = y
c[i,*] = x/x[0]
d[i,*] = y/y[0]
endfor
This version passes READCOL the simple variable names it's expecting, then copies them
into subarrays of the 2-D variables.
If you don't know in advance how many samples are in each file, you could allocate
the 2-d arrays during the first loop iteration:
for i = 0, n-1 do begin
readcol, string(i, F='(I02)')+'.dat',F='D,D', x, y
if (i EQ 0) then begin
samples_per_file = n_elements(x)
a = dblarr(n, samples_per_file)
b = dblarr(n, samples_per_file)
c = dblarr(n, samples_per_file)
d = dblarr(n, samples_per_file)
endif
a[i,*] = x
b[i,*] = y
c[i,*] = x/x[0]
d[i,*] = y/y[0]
endfor
Of course, this all assumes that each file contains the same number of samples. If not,
you'd probably need to change a, b, c, and d to 1-dimensional arrays of pointers,
then use PTR_NEW to allocate memory for each file's data as you read it.
(Note that I've used the square bracket [] notation for array indexing, which I find a
bit easier to read than a(i), b(i) etc. which can be confused with function calls.)

Related

arctangent implementation in TMS320C55X

I'm learning arctangent implementation in TMS320C55x
this is the source code:
;* AR0 assigned to _x
;* AR1 assigned to _r
;* T0 assigned to _nx
PSH T3
|| BSET FRCT ;fractional mode
SUB #1, T0 ;nx-1
MOV T0, BRC0 ;repeat nx times
MOV #2596 << #16, AC3 ; AC3.Hi = C5
MOV #-9464 << #16, AC1 ; AC1.Hi = C3
MOV #32617 << #16, AC2 ; AC2.Hi = C1
*
* Note: loading T3 on the instruction before a multiply that uses it will
* cause a 1-cycle delay.
*
MPYMR T3=*AR0+, AC3, AC0 ; (Prime the Pump)
|| RPTBLOCAL loop1-1
MACR AC0, T3, AC1, AC0
MPYR T3, AC0
||MOV *AR0+, T1 ; (for next iteration)
MACR AC0, T3, AC2, AC0
MPYR T3, AC0
||MOV T1, T3
MOV HI(AC0), *AR1+ ;save result
||MPYR T1, AC3, AC0 ; (for next iteration)
loop1:
POP T3
|| BCLR FRCT ;return to standard C
MOV #0, T0 ;return OK value (no possible error)
|| RET
where _x is vector of input and _r is output. nx is the number of elements.
The question is about constants that assigns to AC3, AC1, AC2. I guess it is coefficients for polynomial approximation but i don't understand how to calculate them
I do not follow the assembly code, but I could guess where those magic coefficients come from.
The code comments suggest C1, C3, C5 are coefficients of a polynomial approximation, and arctan is an odd function, so its Taylor expansion around 0 has indeed only odd powers of x. Comparing C1 = 32617 to 1 in the Taylor expansion y = x - 1/3 x^3 + 1/5 x^5 - 1/7 x^7 + ..., and given the computational context, this further suggests that the result of the calculation is scaled by 2^15 = 32768.
It turns out that y = (32617 x - 9464 x^3 + 2596 x^5) / 32768 is in fact a pretty good approximation of arctan(x) over the interval [-1, 1]. As shown below (verified in wolfram alpha) the largest absolute error of the approximation is less than 1/1000, and is negligible at the endpoints x = ±1 corresponding to y = ±π/4, which is probably desirable in graphics calculations.
As to how the coefficients were actually derived, a crude polynomial best-fit using just 9 control points gives a polynomial y = 32613 x - 9443 x^3 + 2573 x^5 with coefficients already close to the ones used in the posted code. More control points and/or additional conditions to minimize the error at the end points would result in slightly different coefficients, but it's hard to guess how to exactly match the ones in the code without any documentation or clues about the optimization criteria being actually used there.

finding depth of object without use of arithmetics

Without using arithmetics (=< , =>, etc.)!
I have a few separate piles of blocks, for example two piles.
I need a way to figure out if block A sits Higher on any pile than block B.
For example:
is_on_top(Block1,Pile,Block2). %relations of blocks in a particular pile
for example:
is_bellow(a,1,b). % a is bellow b in pile number 1
is_bellow(r,2,e).
is_bellow(f,2,null). % is at top.
....
and so on.
I'm trying to figure out how to write the predicate:
is_higher(Block1,Block2):- %block1 is higher than block2 in Any line.
% to check for the same line if a block is higher than another I'm this
% is Block1 higher than Block2 in THE SAME pile.
taller(Block1, Block2) :-
is_bellow(Block2,_,Block1).
taller(Block1, Block2) :-
is_bellow(Y, I,Block1),
taller(Y, Block2).
is it possible to do it without using arithmetics?
I think I have the terminating condition.
is_higher(Block1,Block2):-
is_bellow(Block1,_,null), is_bellow(Block2,_,X).
X \= null.
is_higher(Block1,Block2):- % don't know how to continue.
From the comments:
I thought something along the lines of digging deeper on both blocks till block one is paired with null, but I cant quite get my head around it.
You are thinking along the correct lines, but your representation of the world seems to confuse you a bit. It becomes easier if we define a cleaner language for talking about blocks and their relationships.
It would have been good if you had posted a complete example. Here is the one I will be using:
is_below(a, 1, b).
is_below(b, 1, null). % topmost on pile
is_below(c, 2, d).
is_below(d, 2, e).
is_below(e, 2, f).
is_below(f, 2, null). % topmost on pile
I understand this to model the following world:
f
e
b d
a c
-----------------
pile 1 pile 2
Now let's talk about concepts related to this world. First... what even is a block? The representation is implicit, but it appears that a block is something that is on a pile. Being "on a pile" is somewhat implicit too, but it means being below something -- another block, or the special non-block atom null.
So this is a block:
% block(X): X is a block
block(X) :-
is_below(X, _Pile, _BlockOrNull).
Prolog can now enumerate blocks:
?- block(X).
X = a ;
X = b ;
X = c ;
X = d ;
X = e ;
X = f.
Note that null is not included, which is good since it is not a block.
Now, is_below complicates things because it talks about non-blocks (namely, null) and also about the numbers of piles, which we don't always need. Let's define a simpler notion of a block being directly on top of another block:
% block_on(X, Y): X is a block directly on top of block Y
block_on(X, Y) :-
is_below(Y, _Pile, X),
block(X).
Note that we use block(X) to make sure we only talk about blocks. Let's test:
?- block_on(X, Y).
X = b,
Y = a ;
X = d,
Y = c ;
X = e,
Y = d ;
X = f,
Y = e ;
false.
Good. Now, let's define notions for being the topmost and the bottommost block on a pile:
% top(X): X is a block that is topmost on its pile
top(X) :-
block(X),
\+ block_on(_OtherBlock, X). % no other block is on X
% bottom(X): X is a block that is bottommost on its pile
bottom(X) :-
block(X),
\+ block_on(X, _OtherBlock). % X is not on any other block
This behaves like this:
?- top(X).
X = b ;
X = f.
?- bottom(X).
X = a ;
X = c ;
false.
And now we can return to your comment:
I thought something along the lines of digging deeper on both blocks till block one is paired with null, but I cant quite get my head around it.
You were talking about digging (upwards?) until you arrive at a topmost block, but in fact what you should be doing is to dig downwards until you arrive at a bottommost block! Hopefully you can see that it's easier to talk about these concepts now that we have given them clearer names, rather than descriptions like being "paired with null".
Let's start with a non-recursive rule for expressing "higher than". Any non-bottom block is definitely "higher than" any bottom block:
% higher_than(X, Y): X is a block higher on any pile than Y
higher_than(X, Y) :-
bottom(Y),
block(X),
\+ bottom(X).
This already captures a lot of relationships:
?- higher_than(X, Y).
X = b,
Y = a ;
X = d,
Y = a ;
X = e,
Y = a ;
X = f,
Y = a ;
X = b,
Y = c ;
X = d,
Y = c ;
X = e,
Y = c ;
X = f,
Y = c ;
false.
Any non-bottom block (b, d, e, f) is higher than any bottom block (a, c).
Now let's do the "digging" part to express that, for example, f is higher than b. Your idea is correct: If we're at some blocks X and Y, and X is directly on top of some block V and Y is directly on top of some block W, and we can somehow establish that V is higher than W, then X is higher than Y! Here's the same idea expressed in Prolog code:
higher_than(X, Y) :-
block_on(X, V),
block_on(Y, W),
higher_than(V, W).
So is f higher than b?
?- higher_than(f, b).
true ;
false.
Nice. And enumerating all "higher than" pairs:
?- higher_than(X, Y).
X = b,
Y = a ;
X = d,
Y = a ;
X = e,
Y = a ;
X = f,
Y = a ;
X = b,
Y = c ;
X = d,
Y = c ;
X = e,
Y = c ;
X = f,
Y = c ;
X = e,
Y = b ;
X = e,
Y = d ;
X = f,
Y = b ;
X = f,
Y = d ;
X = f,
Y = e ;
false.
Most of these are as before, but we got some new pairs as well: e is higher than b and d, f is higher than b, d, and e. And that is all!
Final remark: I'm not an expert on blocks worlds, but my impression was that it is more usual to model the table top as a special "location" rather than having a special marker for "there is nothing above this".
So I would have represented the same world more like this:
pile_on(1, a, table).
pile_on(1, b, a).
pile_on(2, c, table).
pile_on(2, d, c).
pile_on(2, e, d).
pile_on(2, f, e).
You could switch your code to this representation, maybe it would make your life easier. You could also keep the same higher_than definition -- if you adjust the definitions of block and block_on, all the rest can remain the same.
Assuming is_below( A, P, B) means block A is immediately below block B in some pile P, or is topmost in that pile, with B = null, we can code the is_higher( A, B) predicate exactly as you wanted:
we either have one more step to go down the piles and recurse, or we've reached the bottom of the B pile and judge the situation accordingly:
is_higher( A, B) :- % A is higher than B, if
is_below( A2, _, A), % A is atop one
is_below( B2, _, B), % which is _higher_ than that
A \== B, % which B is atop of
is_higher( A2, B2). % (determined _recursively_)
is_higher( A, B) :- % or,
is_below( _, _, A), % A is not bottommost
is_below( B, _, _), % while B is, because
\+ is_below( _, _, B). % there is nothing below B
%% the world: c
%% b e
%% a d
is_below(a,1,b).
is_below(b,1,c).
is_below(c,1,null).
is_below(d,2,e).
is_below(e,2,null).
Testing:
36 ?- findall( A-B, (is_higher(A,B), A\==null), X).
X = [c-b, c-e, b-a, b-d, c-a, c-d, e-a, e-d].

How to only use the lower bounds and upper bounds for quadratic solver qpsolve from Scilab?

I have a simple question. How do I use the command qpsolve from Scilab if I only want to use the lower bounds and upper bounds limit?
ci <= x <= cs
The command can be used as this:
[x [,iact [,iter [,f]]]] = qpsolve(Q,p,C,b,ci,cs,me)
But I want to use it like this:
x = qpsolve(Q,p,[],[],ci,cs,[])
Only ci and cs should explain the limits for vector x. Unfortunately, the command cannot take empty []. Should I take [] as a row vector of ones or zeros?
https://help.scilab.org/docs/6.0.1/en_US/qpsolve.html
In Scilab 5.5.1 , [] works for C and b but not for me. so C = [];b = [];me = 0; should work.
Why
qpsolve is an interface for qp_solve :
function [x, iact, iter, f]=qpsolve(Q,p,C,b,ci,cs,me)
rhs = argn(2);
if rhs <> 7
error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "qpsolve", 7));
end
C(me+1:$, :) = -C(me+1:$, :);
b(me+1:$) = -b(me+1:$);
// replace boundary contraints by linear constraints
Cb = []; bb = [];
if ci <> [] then
Cb = [Cb; speye(Q)]
bb = [bb; ci]
end
if cs <> [] then
Cb = [Cb; -speye(Q)]
bb = [bb; -cs]
end
C = [C; Cb]; b = [b; bb]
[x, iact, iter, f] = qp_solve(Q, -p, C', b, me)
endfunction
It transform every bound constraints into linear constraints. To begin, it swap the sign of the inequality constraints. To do that, it must know me, ie it must be an integer. Since C and b are empty matrices, is value doesn't matter.
Bonus:
if Q is inversible, you could skip the qpsolve macro and write
x = -Q\p
x(x<ci) = ci(x<ci)
x(x>cs) = cs(x>cs)

Count number of vowels in a string using Prolog

I am new in prolog, so i have to explain these code to my class teacher.
can someone please explain this code. Thanks
vowel(X):- member(X,[a,e,i,o,u]).
nr_vowel([],0).
nr_vowel([X|T],N):- vowel(X),nr_vowel(T,N1), N is N1+1,!.
nr_vowel([X|T],N):- nr_vowel(T,N).
output:
1 ?- nr_vowel([a,t,i,k],X).
X = 2.
https://i.stack.imgur.com/dGfU5.jpg
An explanation is indeed highly appropriate.
For example, let us ask the simplest question:
Which solutions are there at all?
Try out out, by posting the most general query where all arguments are fresh variables:
?- nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1.
Hm! That's probably not what you wanted to describe!
So I change your code to:
nr_vowel([], 0).
nr_vowel([X|T], N):-
vowel(X),
nr_vowel(T,N1),
N #= N1+1.
nr_vowel([X|T], N):-
nr_vowel(T,N).
Then we get:
?- nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [a, a],
N = 2 ;
Ls = [a, a, a],
N = 3 ;
etc.
Looks better!
How about fair enumeration? Let's see:
?- length(Ls, _), nr_vowel(Ls, N).
Ls = [],
N = 0 ;
Ls = [a],
N = 1 ;
Ls = [e],
N = 1 ;
Ls = [i],
N = 1 ;
Ls = [o],
N = 1 ;
Ls = [u],
N = 1 ;
Ls = [_2006],
N = 0 ;
Ls = [a, a],
N = 2 ;
Ls = [a, e],
N = 2 .
The first few answers all look promising, but what about Ls = [_2006], N = 0?
This is clearly too general!
You must make your program more specific to avoid this overly general answer.
Here is the problem in a nutshell:
?- nr_vowel([X], N), X = a.
X = a,
N = 1 ;
X = a,
N = 0.
Whaaat? a is a vowel, so why is N = 0??
Here is it in a smaller nutshell:
?- nr_vowel([a], 0).
true.
Whaaaaat??
I leave adding suitable constraints to the predicate as an exercise for you.
The code is simplistic in itself, all it does is count the number of vowels in a list (Guess that's quite evident to you).
Let's take your input as an example, the list is [a,t,i,k]
When you call nr_vowel([a,t,i,k],Z), prolog searches for and unifies the query with the second nr_vowel clause, this is because it is the first clause with a non-empty list input.
Now, vowel(a) returns true, so prolog moves on to the next predicate, which calls nr_vowel([t,i,k],Z). However this time, when prolog tries to unify it with the second nr_vowel, vowel(t) returns false, so it unifies it with the third clause and behaves similarly until the list is empty.
As soon as the list is empty, prolog unifies Z with 0 and starts coming up the recursion levels and does N=N+1 depending on if the caller predicate had a vowel or not, and as soon as it reaches the top of the recursive chain, Z is unified with the final value of N.
In short -
N=N+1 happens if the head of the list is a vowel
N=N i.e. no change occurs if head of list is NOT a vowel.

Octave - Mark zero crossings with an red X mark

Hi have made this code to plot a function.
I need to mark with an red X all the crossings between x = 0 and the blue wave line in the graph.
I have made some tries but with '-xr' in the plot function but it places X marks out of the crossings.
Anyone knows how to do it. Many thanks.
Code:
% entrada
a = input('Introduza o valor de a: ');
% ficheiro fonte para a função
raizes;
% chamada à função
x = 0:.1:50;
or = x;
or(:) = 0;
h = #(x) cos(x);
g = #(x) exp(a*x)-1;
f = #(x) h(x) - g(x);
zeros = fzero(f,0);
plot(x,f(x));
hold on
plot(zeros,f(zeros),'-xr')
hold off
Graph (it only marks one zero, i need all the zero crossings):
As mentioned in the comments above, you need to look for the zeros of your function before you can plot them. You can do this mathematically (in this case set f(x) = g(x) and solve for x) or you can do this analytically with something like fsolve.
If you read the documentation for fsolve, you will see that it searches for the zero closest to the provided x0 if passed a scalar or the first zero if passed an interval. What we can do for a quick attempt at a solution is to pass our x values into fsolve as initial guesses and filter out the unique values.
% Set up sample data
a = .05;
x = 0:.1:50;
% Set up equations
h = #(x) cos(x);
g = #(x) exp(a*x)-1;
f = #(x) h(x) - g(x);
% Find zeros of f(x)
crossingpoints = zeros(length(x), 1); % Initialize array
for ii = 1:length(x) % Use x data points as guesses for fzero
try
crossingpoints(ii) = fzero(f, x(ii)); % Find zero closest to guess
end
end
crossingpoints(crossingpoints < 0) = []; % Throw out zeros where x < 0
% Find unique zeros
tol = 10^-8;
crossingpoints = sort(crossingpoints(:)); % Sort data for easier diff
temp = false(size(crossingpoints)); % Initialize testing array
% Find where the difference between 'zeros' is less than or equal to the
% tolerance and throw them out
temp(1:end-1) = abs(diff(crossingpoints)) <= tol;
crossingpoints(temp) = [];
% Sometimes catches beginning of the data set, filter it out if this happens
if abs(f(crossingpoints(1))) >= (0 + tol)
crossingpoints(1) = [];
end
% Plot data
plot(x, f(x))
hold on
plot(crossingpoints, f(crossingpoints), 'rx')
hold off
grid on
axis([0 20 -2 2]);
Which gives us the following:
Note that due to errors arising from floating point arithmetic we have to utilize a tolerance to filter our zeros rather than utilizing a function like unique.

Resources