 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
pban92
Joined: 23 Nov 2009 Posts: 38
|
Posted: Thu Mar 10, 2011 2:18 pm Post subject: Mirror and shifting of data |
|
|
Hello,
Here is my original function and I am trying to code to generate data to create this mirrored and shifted function as in this figure
To further clarify, my array which contains,
x y
1 10.8
2 10.0
3 9.1
4 8.0
5 6.8
6 6.0
7 5.2
8 4.3
9 3.0
10 0.0
and I am trying to make a new array like,
x y
1 0.0
2 3.0
3 4.3
4 5.2
5 6.0
6 6.8
7 8.0
8 9.1
9 10.0
10 10.8
11 10.8
12 10.0
13 9.1
14 8.0
15 6.8
16 6.0
17 5.2
18 4.3
19 3.0
20 0.0
Here is my code which is giving error,
Code: | real, dimension (100) :: oldvalue
real, dimension (200) :: newvalue
real :: shift = 3.
n=100
do i = 1,n
newvalue (n+i) = oldvalue(i)+shift
end do
do i = 1,n
newvalue (n-i) = oldvalue(i)+shift
end do
|
Any help is appreciated.
Thanks! |
|
Back to top |
|
 |
Wilfried Linder
Joined: 14 Nov 2007 Posts: 314 Location: D�sseldorf, Germany
|
Posted: Thu Mar 10, 2011 6:33 pm Post subject: |
|
|
May be, the last part of your code should be like this:
Code: | do i = 1,n
newvalue (n-i+1) = oldvalue(i)+shift
end do |
Then, the index of newvalue goes from 1 to 100 instead of 0 to 99.
Regards - Wilfried |
|
Back to top |
|
 |
pban92
Joined: 23 Nov 2009 Posts: 38
|
Posted: Thu Mar 10, 2011 6:40 pm Post subject: |
|
|
This solved the problem.
Code: | do i = 1,length
newcore(i) = core(length-i+1)
end do
do i = 1,length
newcore(length+i) = core(i)
end do |
Many thanks for the response![/code] |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Mar 11, 2011 1:03 am Post subject: |
|
|
You may like to consider the following alternatives, using a DO loop or array syntax to achieve what you want. I'm not sure if any is better than the other, as they all achieve a result.
Code: | call do_syntax
!
call array_syntax
end
subroutine do_syntax
integer*4 list(4), new_list(8), length, i
!
length = size(list)
list = (/ 1, 2, 3, 4 /)
!
do i = 1,length
new_list(length-i+1) = list(i)
new_list(length+i) = list(i)
end do
write (*,'(20i4)') new_list
!
do i = 1,length
new_list(i) = list(i)
new_list(length+i) = list(length-i+i)
end do
write (*,'(20i4)') new_list
!
end
Subroutine array_syntax
integer*4, allocatable :: list(:), new_list(:)
integer*4 length, i
!
length = 5
allocate (list(length))
allocate (new_list(length*2))
!
forall (i=1:length) list(i) = i*2-1
new_list(1:length) = list(1:length)
new_list(length+1:length*2) = list(length:1:-1)
write (*,'(20i4)') new_list
!
forall (i=1:length) list(i) = (length-i)*2+1
new_list(1:length) = list(1:length)
new_list(length+1:length*2) = list(length:1:-1)
write (*,'(20i4)') new_list
!
new_list = 0
forall (i=1:length)
new_list(i) = (length-i)*2+1
new_list(length+i) = i*2-1
end forall
write (*,'(20i4)') new_list
!
end
|
|
|
Back to top |
|
 |
IanLambley
Joined: 17 Dec 2006 Posts: 506 Location: Sunderland
|
Posted: Fri Mar 11, 2011 3:20 pm Post subject: |
|
|
Alternatively, if X is actually the array position, then you could just calculate an alternative array subscript to pull out the Y value as in:
Let
n = number of entries in original array "y"
i = new array position
j = equivalent array position in first array
Array y is dimensioned to n
Code: |
dimension y(10)
data y/10.8, 10.0, 9.1, 8.0, 6.8, 6.0, 5.2, 4.3, 3.0, 0.0 /
n=10
do i=1,n*2
print *,i,y_mirror(y, n, i)
enddo
end
real function y_mirror(y, n, i)
dimension y(n)
j = abs(i-1) - int( (i-1) / n ) + 1
y_mirror = y( j )
end
|
and if you want to carry on outside of the range n*2, then the function becomes:
Code: |
real function y_mirror(y, n, i_input)
dimension y(n)
i = mod( (i_input-1), n*2 ) + 1
j = abs(i-1) - int( (i-1) / n ) + 1
y_mirror = y( j )
end
|
Hope this helps.
Ian |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Sat Mar 12, 2011 12:53 pm Post subject: |
|
|
Ian,
Your code reminds me of JDATE. (I'll understand that integer code one day.)
I'd prefer a simpler form of j=, possibly:
j = min (i, 2*n+1-i) ! valid for i in range 1:2n
or more simply you could use an IF
IF (i > n) then
j = 2*n+1-i
else
j = i
end if
I've been coming back to code I wrote years ago and now want it to be easier to understand. It saves time, especially if it needs changeing. Those old integer expressions are not easy to modify.
John |
|
Back to top |
|
 |
IanLambley
Joined: 17 Dec 2006 Posts: 506 Location: Sunderland
|
Posted: Sat Mar 12, 2011 8:27 pm Post subject: |
|
|
Well done John, it is getting simpler all the time. And yes, coming back to old code can be tricky. I think that good commenting is the answer. Once when a couple of us tried to delve into some Z80 assembler, written by someone else who had left the company, we found it was fully commented. Unfortunately one line of code was commented with the phrase "Old Indian trick" - very helpful I don't think.
Of course, you can point out that my miserable attempt avoided useful comments, but it was just intended to take the subject in another direction.
Actually, If you look at the original post, 10.8 is the first element in the input array and is required to be at the 10th and 11th position in the output, your equation does not do this inversion. It would need to be:
Code: | j = n+1 - min(i, 2*n+1-i)
|
No doubt you can simplify this equation as I've just run out of energy for today.
The if-then-else version would just need:
adding after the end statement or including in each equation.
Regards
Ian |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|