OK so here is the problem. In my assignment I should create a (3,1000) matrix and after I created it I should delete RANDOMLY 271 rows of the matrix. At the end I should obtain a (3,729) Matrix with all the initial values except the one I deleted corresponding to the random numbers.
To do so I wrote this script where Mc=1000 N=729
h=1
do a=1, (Mc-N)
call random_number(rand_num)
rand_num=int(rand_num*Mc)-1
!print*, rand_num
do b=1, Mc
if (b /= rand_num) then
NMatrix(:,h) = Matrix(:,b)
h=h+1
else
h=h
endif
enddo
enddo
But when I run it it reports me this error: Program receiver signal SIGABRT : Process abort signal.
What should I do? Please it's really important
I know there is some problem with the do loops and the memory of the arrays, but I cannot get to the point. Can you please ask me?
Here an example ouput of what you are asking for (I think).
rows=3, cols=1000
1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 10.00 11.00 12.00 ...
1001. 1002. 1003. 1004. 1005. 1006. 1007. 1008. 1009. 1010. 1011. 1012. ...
2001. 2002. 2003. 2004. 2005. 2006. 2007. 2008. 2009. 2010. 2011. 2012. ...
rows=3, cols=729
1.000 3.000 4.000 9.000 10.00 11.00 12.00 13.00 14.00 16.00 17.00 19.00 ...
1001. 1003. 1004. 1009. 1010. 1011. 1012. 1013. 1014. 1016. 1017. 1019. ...
2001. 2003. 2004. 2009. 2010. 2011. 2012. 2013. 2014. 2016. 2017. 2019. ...
Note that by convention, the 1st index is the rows, and the 2nd index is the columns. So you are asking to remove 271 columns from the matrix.
I decided to use an array of index values indx=[1,2,3,4 .. n]
, which I shuffle randomly, then slice off the last 271 values (keep n
entries) and then sort back to increasing order.
Finally, the result is essentially NMatrix(:,:) = Matrix(:, indx)
or in my case I call them a
and b
in my function.
function RemoveRandomColumns(a,n_col) result(b)
real, intent(in) :: a(:,:)
integer, intent(in) :: n_col
real, allocatable :: b(:,:)
integer :: i,j,n,m,t
integer, allocatable :: indx(:)
real :: u !used in shuffle part
m = size(a, 1)
n = size(a, 2)
! must remove m-n_col columns from a
allocate(indx(n))
indx = [ (i,i=1,n) ]
! indx = [1,2,3,4,5,6,7,8,..,n]
! suffle the index
call RANDOM_SEED()
do i=1, n
call RANDOM_NUMBER(u)
j = 1 + floor(u*(n-1))
t = indx(i)
indx(i) = indx(j)
indx(j) = t
end do
! indx = [18,10,3,16,21,...]
! take only n_col items
indx = indx(1:n_col)
! indx = [18,10,3,...]
! sort the index
do i=1, n_col
do j=1, i-1
if(indx(i)<indx(j)) then
t = indx(i)
indx(i) = indx(j)
indx(j) = t
end if
end do
end do
! indx = [2,3,4,6,7,9,..,n]
! now slice the array to get the resukt
allocate(b(m,n_col))
do j=1, m
b(j,:) = a(j,indx)
end do
end function
and the sample code to test the above is
program FortranProgram1
use, intrinsic :: iso_fortran_env
implicit none
integer, parameter :: Mc = 1000, n = 729
! Variables
real :: matrix(3, Mc)
real :: reduced(3, n)
integer :: i,j
do j=1, 3
do i=1, Mc
matrix(j,i) = real(Mc*(j-1)+i)
end do
end do
print '("rows=",g0,", cols=",g0)', size(matrix,1), size(matrix,2)
print '(*(g0.4," "))', matrix(1,1:12), "..."
print '(*(g0.4," "))', matrix(2,1:12), "..."
print '(*(g0.4," "))', matrix(3,1:12), "..."
print *, ""
reduced = RemoveRandomColumns(matrix, n)
print '("rows=",g0,", cols=",g0)', size(reduced,1), size(reduced,2)
print '(*(g0.4," "))', reduced(1,1:12), "..."
print '(*(g0.4," "))', reduced(2,1:12), "..."
print '(*(g0.4," "))', reduced(3,1:12), "..."
contains
function RemoveRandomColumns(a,n_col) result(b)
...
end function
end program