# Assignments of Elements between differently ranked arrays (fortran95)

1. Apr 29, 2014

### GeneralGrant

Thank you for reading my post, i have been known to be long winded but i put a abridged version of my question and sectional labels so it can be skimmed easily for relevant information.

note: I Wrote a very explanatory post, which had sections and was written very nicely but i lost it because when i went to post it i put int he wrong password and when i went back it was gone and it didn't save in a draft somewhere(or did it?). This is a bit lazier and more poorly written but the question is this:

I am coding in Fortran 95

THE SHORT VERSION:

Can i assign the value of a single element from a rank 1 array to be the value of a rank zero variable.
Such as: Alpha = Z(1:1), Beta = Z(1:2)

Can i re-define the structure of an array to an equivalent array
Such as: A(n:1) --> A(n) or A(1:n) ---> A(n)

THE LONG VERSION/THE SET UP AND CONTEXT

Using a chebyshev routine i acquired the zero values for a function which plots the trajectories of a mass. the functions do loop ends when (f(1) >= xfinal) and gives as the result the difference between the y(3) value and the desired y(3) value(y(3) is the y axis value, y(1) is the x axis value). It is a boundary value problem, given v0, x0, y0, xfinal, and yfinal find the angle which makes this true. The chebyshev yields the zero values in the form z0(1:iz0) where z0 is the array of the angles which are solutions to the problem, and iz0 is an integer for the number of solutions(which is 2).

I want to extract the values from z0 and assign them to a variable and run the rk4step function to plot the trajectories which solve the problem. I have technically completed the assignment of finding the zero values using the "shoot" method. But, i want to plot them and i could only do it by using human power to read the printed values and manually put them into a new program. There must be a way to do this else it could become very annoying/cumbersome in a more complex problem.

I tried to do

Alpha = zo(1:1)
alpha2 = zo(1:2)

But it says the ranks don't match so it won't compile

I tried

Alpha(1) = zo(1:1)

same thing

i tried

Alpha(1:1) = z0(1:1)

but then it fails when

y(2) = mass*v0*cos(alpha(1:1)

because the ranks don't match again

THE QUESTIONS

Can i extract the value from the array z0 and assign it to a variable defined in a different way(rank 0) or do i have to change all my variables to match?

Can I re-define my z0(1:iz0) to be some new array formatted as z02(iz0) so that it matches the format of y(n_eq)?

THE RANT:
What if this program had multiple subroutines which had variables defined differently, and they are interconnected, and i couldn't use the value from one routine in the other routine just because one can not extract the values from a rank 2 array and put them into a rank 1 array, or from a rank 1 array into a rank 0 array.

This seems like a very limiting thing, I have heard of something called a "leading dimensional array" when we did matrices, must i use the highest dimensional array throughout all the program or is there a way to split the arrays, or down-rank the values in them for use in simpler/lower dimensional programs?

so far, for the most part, online i have read the answer is NO, i cannot assign values to differently ranked variables. But i did find something called "array slicing"??? but i couldn't figure out how to apply it to my problem as the examples it gave seemed irrelevant.

2. Apr 29, 2014

### Staff: Mentor

Yes, provided that I'm understanding what you're asking. What you're calling a rank zero variable is usually called a scalar.

Given the two declarations below, the assignment statement would cause 0.1 to be stored in b.
Code (Text):
REAL, DIMENSION(3) :: a = (/ 0.1, 0.2, 0.3 /)
REAL b

b = a(1)

I haven't written any Fortran code for more than 15 years, so I'm a little rusty, but I think you are not understanding what 1:n means in A(1:n). A is a one-dimension array (or rank 1 array) whose indexes are 1, 2, 3, ..., n. To access the element at index j (where 1 ≤ j ≤ n), you write A(j).

I don't believe the compiler would allow you to declare an array like this - A(n:1), because the indexes would have to run from n (which I assume is larger than 1) down to 1.

3. Apr 29, 2014

### AlephZero

I think you are getting confused by the use of ":" here.

If you have a
Code (Text):

REAL, DIMENSION(10) :: Z
REAL :: A

You access the the first element of Z as a scalar with Z(1), and you can assign A = Z(1).

Your Z(1:1) is a rank one array of length 1, containing the first element of Z. You can't assign that array to a scalar.

Something like Z(4:6) is a rank one array of length 3, containing elements 4 5 and 6 of Z. So you can write things like
Code (Text):

Z(1:3) = Z(4:6) + Z(8:10)

which is equivalent to
Code (Text):

Z(1) = Z(4) + Z(8)
Z(2) = Z(5) + Z(9)
Z(3) = Z(6) + Z(10)

You can even write something like
Code (Text):

Z(1:3) = 2*Z(4:6) + 3

which is equivalent to
Code (Text):

Z(1) = 2*Z(4) + 3
Z(2) = 2*Z(5) + 3
Z(3) = 2*Z(6) + 3

In other words you can mix up arrays and scalars within an arithmetic expression on the right hand side of the = sign, but the things on the left and right sides of the = sign must be both scalars, or both arrays with the same rank and size (dimension).

4. Apr 29, 2014

### AlephZero

Actually that is legal, but probably not useful. It represents an array of length zero. There are times when zero length arrays are convenient, e,g to write code like
Code (Text):

do i = 1, n
a(1:i-1) = something
a(i)     = something else
a(i+1:n) = something other
end do

without the need to mess around with IF statements when i = 1 and i = n

And you can have arrays that count backwards if you want, for example A(10:1:-1)

Fortran 90/95 Array notation and Fortran 77 do loops work the same way for this type of coding.

5. Apr 30, 2014

### CraigDxHypo

A simple rule for array expressions in FORTRAN 90 assignment statement

Disclaimer: I’m a veteran (~30 year) professional computer programmer, and the first compiled language I ever used, in the late 1970s, was FORTRAN, but I’ve not used FORTRAN of any sort since the early 1980s, so know of FORTRAN 90 and 95 only what I’ve read about it. As I wouldn’t be a very successful veteran programmer if I wasn’t good at answering questions about thinks about which I know very little , I think I can answer (guessing) yours, GeneralGrant, just from reading FORTRAN 90 documentation. FORTRAN 95 appears to me to differ little from FORTRAN 95 regarding to statements with array selection expressions (eg: “a(0:n)=b(0:n)*c(1,10:10+n)”).

Yes, but not with that statement.

The relevant rule, which I read at https://orion.math.iastate.edu/burkardt/papers/fortran_arrays.html#Array_Expressions [Broken], is “The array expression and the array into which the value are stored must normally have the same shape. The only exception is that an array may be assigned a scalar value, such as "A=1.0".’

So correct statements include: [noparse]Alpha(:) = Z(1), Beta(1:2) = Z(2), Alpha(3:5) = Z(6:8)[/noparse]

These are OK per the rule, because Z(1) and Z(2) are scalar values, while Alpha(3:5) and Z(6:8) have the same shape, a 1-dimensional array of size 3.

Last edited by a moderator: May 6, 2017
6. May 2, 2014

### GeneralGrant

Thanks guys for the responses, timely too.

I was able to successfully plot all possible solutions, since this is my third attempt at writing a reply, i was not logged in and deleted my replays twice now, and i have work to do i will just say that from reading your responses i now understand the notational error i was making in the difference between how commas and colons are used in representing arrays. Using

Alpha = Z(i)

was all i needed to do, i then used a do loop so that it did all possible solutions and wrote a file which could plot each one from the Runga-Kutta i had written.

colons are for establishing a run a numbers for a single indicee
and commas are used for separating different indices

Thank you all again, this was very helpful and will be helpful in my upcoming exam.