Store elements in a vector Fortran - vector

I have a very simple do loop in which I want to save (to store) the elements of a vector that is computed in the cycle to another one, such as I can recall the elements of this second vector outside the loop.
My naively test is as follow:
program test
implicit none
integer :: num,i
real*8, DIMENSION(3, 1) :: pos
real*8, dimension(:),allocatable :: x(:)
real*8 :: step,delta
pos = 0.0 ! clear the vector all components are equal to zero
pos(1,1)=1. ! only first elements of the vector 'pos' of object 1 is diff. from zero
num=1000
delta = 1.
step = 0.
allocate(x(num)) ! allocate a vector with dimension equal to num
x=0.
do while ( step < num )
pos(1,1) = pos(1,1) + 0.5d0 ! move the objects
x=pos(1,1) ! store the elements of vector 'pos' in vector 'x'
step = step + delta
end do
print*, x(120) ! print the 120th elements of the vector x
end program test
I think the problem is on how i pass the elements from 'pos' to 'x' vector.
Thanks a lot for your help.

This statement
allocate(x(num)) ! allocate a vector with dimension equal to num
makes x a vector with num (i.e. 1000) elements. The next statement
x=0.
sets every element of x to 0.0. So far so good. Then the code enters the loop where this statement
x=pos(1,1) ! store the elements of vector 'pos' in vector 'x'
repeatedly sets every element of x to the latest value of pos(1,1). That's probably not what you want to do. I think the easiest fix would be to rewrite the loop like this
do step = 1,1000
pos(1,1) = pos(1,1) + 0.5d0 ! move the objects
x(step) = pos(1,1) ! store the elements of vector 'pos' in vector 'x'
end do
I'm not sure exactly what you are trying to do, it looks as if you are trying to populate x with the terms in the arithmetic series 1 + n*0.5, n = [0,999]. A neater way to do that might be to modify what you have so that x is indexed from 0, perhaps
allocate(x(0:num-1))
and then simply use a loop such as
do step = 1,999
x(step) = x(step-1)+0.5
end do
I'm not sure why you involve pos in setting the values of x at all.

Related

Tensor mode n product in Julia

I need tensor mode n product.
The defination of tenosr mode n product can be seen here.
https://www.alexejgossmann.com/tensor_decomposition_tucker/
I found python code.
I would like to convert this code into julia.
def mode_n_product(x, m, mode):
x = np.asarray(x)
m = np.asarray(m)
if mode <= 0 or mode % 1 != 0:
raise ValueError('`mode` must be a positive interger')
if x.ndim < mode:
raise ValueError('Invalid shape of X for mode = {}: {}'.format(mode, x.shape))
if m.ndim != 2:
raise ValueError('Invalid shape of M: {}'.format(m.shape))
return np.swapaxes(np.swapaxes(x, mode - 1, -1).dot(m.T), mode - 1, -1)
I have found another answer using Tensortoolbox.jl
using TensorToolbox
X=rand(5,4,3);
A=rand(2,5);
ttm(X,A,n) #X times A[1] by mode n
One way is:
using TensorOperations
#tensor y[i1, i2, i3, out, i5] := x[i1, i2, i3, s, i5] * a[out, s]
This is literally the formula given at your link to define this, except that I changed the name of the summed index to s; you can you any index names you like, they are just markers. The sum is implicit, because s does not appear on the left.
There is nothing very special about putting the index out back in the same place. Like your python code, #tensor permutes the dimensions of x in order to use ordinary matrix multiplication, and then permutes again to give y the requested order. The fewer permutations needed, the faster this will be.
Alternatively, you can try using LoopVectorization, Tullio; #tullio y[i1, i2, ... with the same notation. Instead of permuting in order to call a library matrix multiplication function, this writes a pure-Julia version which works with the array as it arrives.

What are the rules for threading a function over a vector in R?

I have some code which I call with two vectors of different length, lets call them A and B. However, I wrote the function having in mind a single element of A with the expectation that it will be automatically threaded over A. To be concrete,
A <- rnorm(5)
B <- rnorm(30)
foo <- function(x,B){
sum( cos(x*B) ) # calculate sum_i cos(x*B[i])
}
sum( exp(foo(A,B)) ) # expecting this to calculate the exponent for each A[j] and add over j
I need to get
Σ_j exp( Σ_i cos(A[j]*B[i])
and not
Σ_ij exp(cos(A[j]*B[i])) OR exp(cos(Σ_ij A[j]*B[i]))
I suspect that the last R expression is ambiguous, since the declaration of foo does not know B is always a vector. What are the formal rules and am I right to worry about the ambiguity?
If we want to loop over the 'A', then use sapply , and apply the foo on each of the elements of 'A' with anonymous function call and get the sum of the output vector
sum(exp(sapply(A, function(x) foo(x, B))))
In the OP's example with the expression foo(A, B), the product A*B is computed first, and since the lengths of A and B are unequal, the recycling rule takes priority. There is no error message coming out, just because by pure luck the vector length of one is a multiple of the other.
You can also Vectorize the x input. I think this is what you were expecting. At the end of the day, this will work it's way down to an mappy() implementation which is a multivariate sapply, so probably best to just do it yourself as with the solution from akrun.
foo2 <- Vectorize(foo, "x")
sum(exp(foo2(A, B)))
The "formal rules" as you put them is quite simply how R does help("Arithmetic").
The binary operators return vectors containing the result of the element by element operations. If involving a zero-length vector the result has length zero. Otherwise, the elements of shorter vectors are recycled as necessary (with a warning when they are recycled only fractionally). The operators are + for addition, - for subtraction, * for multiplication, / for division and ^ for exponentiation.
So when you use x*B, it is doing element-wise multiplication. Nothing changes when you pass A into the function instead of x.
Simply go through your lines one at a time.
x*B will be a vector of length max(length(x, B)). When they are not of the same length, R will recycle elements of the shorter vector (i.e., repeat them).
cos(x*B) will be a vector of the same length as step (1), but now the cosine of that value.
sum( cos(x*B) ) will sum that vector, returning a single number.
foo(A,B) does steps (1) through (3), but with your defined A and B. Note that in your example A is recycled 6 times to get to the length of B. In other words, what you entered as A is being used as rep(A, 6) in the multiplication step. Nothing about a function definition in R says that foo(A,B) should be repeated for each element of vector A. So it behaves literally as you wrote it, basically swapping in A for x in the function code.
exp(foo(A,B)) will take the result from foo from step 3 (which is a scalar) and raise it to an exponent.
sum( exp(foo(A,B)) ) does nothing, since step (5) is a scalar, there is nothing to sum.

Cumulative Integration Options With Julia

I have two 1-D arrays in which I would like to calculate the approximate cumulative integral of 1 array with respect to the scalar spacing specified by the 2nd array. MATLAB has a function called cumtrapz that handles this scenario. Is there something similar that I can try within Julia to accomplish the same thing?
The expected result is another 1-D array with the integral calculated for each element.
There is a numerical integration package for Julia (see the link) that defines cumul_integrate(X, Y) and uses the trapezoidal rule by default.
If this package didn't exist, though, you could easily write the function yourself and have a very efficient implementation out of the box because the loop does not come with a performance penalty.
Edit: Added an #assert to check matching vector dimensions and fixed a typo.
function cumtrapz(X::T, Y::T) where {T <: AbstractVector}
# Check matching vector length
#assert length(X) == length(Y)
# Initialize Output
out = similar(X)
out[1] = 0
# Iterate over arrays
for i in 2:length(X)
out[i] = out[i-1] + 0.5*(X[i] - X[i-1])*(Y[i] + Y[i-1])
end
# Return output
out
end

Erlang: Get the first element of each tuple in a list

I can get the first element of every tuple if I create the list at the same time, for example
[element(2,X) || X <- [{1,2},{3,4}]].
[2,4]
This works as it should.
I want to be able to create the list before I try to do anything with it
Ex: Create the list
X = [{1,2,3},{3,4,5}].
[{1,2,3},{3,4,5}]
Then get the first element of each tuple
element(1,X).
But I get the error
** exception error: bad argument
in function element/2
called as element(1,[{1,2,3},{3,4,5}])
I want this code to give the same results that my first example gave
Use List Comprehension with a generator(<-)
X = [{1,2,3},{3,4,5}].
[A || {A,_,_} <- X].
This is saying that we want to print element A, where A is taken from the tuple {A,_,_}(a tuple which we generate from each tuple in X). Because we are only selecting A and don't care about the second and third element, they are set equal to _.
Output
1> X = [{1,2,3},{3,4,5}].
[{1,2,3},{3,4,5}]
2> [A || {A,_,_} <- X].
[1,3]

New to SML / NJ. Making a custom insert function

Define a function that, given a list L, an object x, and a positive
integer k, returns a copy of L with x inserted at the k-th position.
For example, if L is [a1, a2, a3] and k=2, then [a1, x, a2, a3] is
returned. If the length of L is less than k, insert at the end. For
this kind of problems, you are supposed not to use, for example, the
length function. Think about how the function computes the length. No
'if-then-else' or any auxiliary function.
I've figured out how to make a function to find the length of a list
fun mylength ([]) = 0
| mylength (x::xs) = 1+ mylength(xs)
But, as the questions states, I can't use this as an auxiliary function in the insert function. Also, i'm lost as to how to go about the insert function? Any help or guidance would be appreciated!
Here's how to do this. Each recursive call you pass to the function tail of the list and (k - 1) - position of the new element in the tail of the list. When the list is empty, you construct a single-element list (which was given to you); when k is 0, you append your element to what's left from the list. On the way back, you append all heads of the list that you unwrapped before.
fun kinsert [] x k = [x]
| kinsert ls x 0 = x::ls
| kinsert (l::ls) x k = l::(kinsert ls x (k - 1))
I used a 0-indexed list; if you want 1-indexed, just replace 0 with 1.
As you can see, it's almost the same as your mylength function. The difference is that there are two base cases for recursion and your operation on the way back is not +, but ::.
Edit
You can call it like this
kinsert [1,2,3,4,5,6] 10 3;
It has 3 arguments; unlike your length function, it does not wrap arguments in a tuple.
Here's how I'd approach it. The following assumes that the list item starts from zero.
fun mylength (lst,obj,pos) =
case (lst,obj,pos) of
([],ob,po)=>[ob]
| (xs::ys,ob,0) => ob::lst
| (xs::ys,ob,po) => xs::mylength(ys,obj,pos-1)

Resources