I have a simple question about arrays of 2 dimensions in Fortran 95 (i.e., matrices). By what I know, mathematics define an element inside of a matrix as Aij, where i represents its line and j its column. Well, if I simply code write(*,*) Matrix, the result has lines and columns inverted! Take the following example code:
program TEST
implicit none
integer :: P(3,3), i
P(1,1)=1
P(1,2)=2
P(1,3)=3
P(2,1)=4
P(2,2)=5
P(2,3)=6
P(3,1)=7
P(3,2)=8
P(3,3)=9
do i=1,3
write(*,"(3(I1,1X))") P(i,1:3)
enddo
write(*,*)
write(*,"(3(I1,1X))") P
end program TEST
By using the loop above (which fixes a line and then print each column inside of it), I get the result I expected:
1 2 3
4 5 6
7 8 9
Now by using the last statement write(*,"(3(I1,1X))") P, I get:
1 4 7
2 5 8
3 6 9
Am I doing something wrong here?
When you output an entire array as an entity, Fortran outputs the array in its internal memory layout. What you are seeing is that Fortran is a column-major language. See http://en.wikipedia.org/wiki/Row-major_order#Column-major_order
Related
In the following program I define an array of derived variables, which have two properties, A and B. I would like to have a subroutine that performs some function (e.g. calculate the gradient or max or min) on a property A or B. Properties A and B are arrays as well.
1 module example
2 implicit none
3 type array
4 real :: A(2) ! property A
5 real :: B(2) ! property B
6 end type array
7 contains
8 subroutine use_property(C1,C2)
9 implicit none
10 real :: C1(2),C2(2)
11 !Function involving A or B
12 end subroutine use_property
13 end module example
14 !-----------------------------------
15 program test
16 use example
17 implicit none
18 type(array) :: grid(2)
19
20 call use_property(grid(1)%A,grid(2)%A)
21 call use_property(grid(1)%B,grid(2)%B)
22 end
The previous code works well. However, if the length of the variable "grid" increases by 3 then calling the subroutine would require something like:
use_property(grid(1)%B,grid(2)%B,grid(3)%B,grid(4)%B,grid(5)%B).
I was wondering if there is a more elegant way to achieve the same result of applying a function to a specific element of an array of derived variables.
I have the following output from a code:
MAT_ArrayT - 6x1 cell
MAT_ArrayY - 6x1 cell
Inside each of the it looks as following:
10000x1 double
9000x1 double
8000x1 double
7000x1 double
6000x1 double
5000x1 double
I would like to have a plot where I get 6 lines that fit to each other.
The result I want to get is as follows:
for i = 1:6
plot(MAT_ArrayT{i,:},MAT_ArrayY{i,:})
end
but without for loop since it takes much longer where I need to draw 1k+ lines.
Thank you.
The quick-and-dirty solution is as in my answer to your previous question, padding the shorter vectors with NaN. NaN points are not plotted.
If you hand Matlab's plot function an array, it will plot each column of the array as it's own line. For example:
A = 1:2:20;
B = 1:10;
C = [A', B']
plot(C)
Produces
C =
1 1
3 2
5 3
7 4
9 5
11 6
13 7
15 8
17 9
19 10
As we can see, plot() has plotted the first column of C as the blue line, and the second column of C as the orange line, and we did it with just one line of code. If you can set up your cell arrays such that each line you want to plot is its own column, this should be able to speed things up for you.
I am trying to plot a figure using three matrices but somehow I couldn't understand. I have three matrices and an array. Suppose,
A =
1 2 3
4 5 4
7 8 9
B =
2 3 13
5 11 10
9 7 6
C =
1 2 3
2 3 13
5 11 10
and an array
Y= [0.001 0.0002 0.0004].
Now I want to plot it in such a way that array values should be on y axis while against 0.001, 0.002 and 0.0004 the matrices value should be arranged.
for examples, the y=0.001, A(1,1)=1, y=0.0002, B(1,1)=2 y=0.0004, C(1,1)=1 for a single line.
and similarly process goes for A(i,j),B(i,j) and c(i,j) points using loop to plot all lines on a single figure.
Thanks
So, the first plot is plot([1,2,1],Y), the next one is plot([2,3,2],Y) and so on?
If so, you could do it like that
X = cat(3,cat(3,A,B),C);
X = reshape(permute(X,[3,1,2]),3,9);
plot(X,Y,'--x');
which gives a plot like this:
Is this what you were looking for? If not, I didn't understand your question well and I'd like to ask you to rephrase it.
You can create a 3D array (tensor) and access it in a loop.
T(:,:,1) = A;
T(:,:,2) = B;
T(:,:,3) = C;
figure;
for idi = 1:size(A,1)
for idj = 1:size(A,2)
plot(squeeze(T(idi,idj,:)).',Y); hold on;
end
end
Accessing the third dimension is not fastest operation (as they are not store sequential in memory) and if the matrices are larger you might consider reshape.
I did not understand you wanted the vector Y to be on the x-axis or y-axis (and neither of those plots make sense to me) but I am sure you can modify the code from here for your needs.
I have a matrix with n rows and 3 columns, and I should multiply row n column 2 with row n column 3.
So if I have a matrix that looks like this:
1 2 3
4 5 6
7 8 9
Then I should multiply 2 with 3, 5 with 6 and 8 with 9, and create a matrix or an array that holds results:
6
30
72
How can I do that in C?
Since you are interested in learning C, an outline should do :-) The output is going to be a single column vector. Input to your function is a matrix, of some dimension p x q, and two column numbers c1 and c2. You can not skin it at least two ways.
a function that does exactly what your problem asks, iterating x[1..p][c1] and x[1..p][c2] (so loop variable will be row numbers 1..p, and multiply them, producing result[1..p]
a function that returns a column vector from a given matrix, and then another function that does the element-wise product of two vectors as above. This jimho might be a more interesting option.
HTH
I have a 4-dimensional dictionary I made with a Python script for a data mining project I'm working on, and I want to read the data into Matlab to do some statistical tests on the data.
To read a 2-dimensional matrix is trivial. I figured that since my first dimension is only 4-deep, I could just write each slice of it out to a separate file (4 files total) with each file having many 2-dimensional slices, looking something like this:
2 3 6
4 5 8
6 7 3
1 4 3
6 6 7
8 9 0
This however does not work, and matlab reads it as a single continuous 6 x 3 matrix. I even took a look a dlmread but could not figure out how to get it do what I wanted. How do I format this so I can put 3 (or preferably more) dimensions in a single file?
A simple solution is to create a file with two lines only: the first line contains the target array size, the second line contains all your data. Then, all you need to do is reshape the data.
Say your file is
3 2 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
You do the following to read the array into the variable data
fid = fopen('myFile'); %# open the file (don't forget the extension)
arraySize = str2num(fgetl(fid)); %# read the first line, convert to numbers
data = str2num(fgetl(fid)); %# read the second line
data = reshape(data,arraySize); %# reshape the data
fclose(fid); %# close the file
Have a look at data to see how Matlab orders elements in multidimensional arrays.
Matlab stores data column wise. So from your example (assuming its a 3x2x3 matrix), matlab will store it as first, second and third column from the first "slice", followed by the first, second third columns from the second slice and so on like this
2
4
3
5
6
8
6
1
7
4
3
3
6
8
6
9
7
0
So you can write the data out like this from python (I don't know how) and then read it into matlab. Then you can reshape it back into a 3x2x3 matrix and you'll retain your correct ordering.