|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
colt1954
Joined: 21 Dec 2010 Posts: 81
|
Posted: Tue Mar 15, 2011 12:42 pm Post subject: crazy array values |
|
|
Any ideas why this program which attempts to sift certain array values hence the first IF/DO loop section (relevant snapshot below) it prints out sensible expected values within the initial do loops so it works thus far (i put the write command in simply as a check), but when I finally change the order it prints out (which I need to do) in the second set of do loops the values come out stupid e.g 4.034E0129....the FX,FY..etc arrays are declared as real*8, setting them up simply as dimension FX(6,12)..simply does not work etc. The GENG arrays are complex.
DO J=1,6
DO M=2,512
IF(ABS(THETA(2,M)-(RPM*J/120)).LT.0.001)THEN
FX(J,NRPM)=ABS(GENG(31,M))
FY(J,NRPM)=ABS(GENG(32,M))
FZ(J,NRPM)=ABS(GENG(33,M))
MX(J,NRPM)=ABS(GENG(34,M))
MY(J,NRPM)=ABS(GENG(35,M))
MZ(J,NRPM)=ABS(GENG(36,M))
WRITE(*,*)RPM,FX(J,NRPM),FY(J,NRPM),FZ(J,NRPM),MX(J,NRPM),MY (J,NRPM),MZ(J,NRPM)
ENDIF
ENDDO
ENDDO
IF(NRPM.EQ.11)THEN
DO J=1,6
DO N=1,NRPM
ESP=RPMIN+(N-1)*RPMI
EO=J*0.5
WRITE(*,*)ESP,EO,FX(J,N),FY(J,N),FZ(J,N),MX(J,N),MY(J,N),MZ(J,N)
ENDDO
ENDDO
ENDIF
Here is a sample snapshot of output sets for last write section for two rpm values 1500/2000:
1500.00 0.500000 0.00000000000 0.00000000000 0.00000000000
0.00000000000 0.00000000000 0.00000000000
2000.00 0.500000 0.00000000000 -1.420806014199E+0241 0.00000000000
2.336470151337E-0307 2.368279619495E-0308 0.00000000000 |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Tue Mar 15, 2011 10:26 pm Post subject: Re: crazy array values |
|
|
I can see a few things. But it is difficult to see what you are trying to do.
You seem to be overwriting the elements of the arrays with each pass through the first M loop. E.g. should you have FX(J,M) = ... and not FX(J,NRPM) = ..' ? Or should NRPM be calculated inside the M loop? or inside the IF block (I think the latter.)
I think your check PRINT simply gives you the last calculation. It doesn't tell you that you are over-writing all the earlier ones.
This is my guess at what you need. I hope it helps some. You might want to consider whether the indenting makes it clearer too, and whether it would have helped you seen the answer yourself.
Code: |
DO J=1,6
! Zero index to output arrays
NRPM = 0
DO M=2,512
IF(ABS(THETA(2,M)-(RPM*J/120)).LT.0.001)THEN
! Increase index to output arrays
NRPM = NRPM + 1
FX(J,NRPM)=ABS(GENG(31,M))
FY(J,NRPM)=ABS(GENG(32,M))
FZ(J,NRPM)=ABS(GENG(33,M))
MX(J,NRPM)=ABS(GENG(34,M))
MY(J,NRPM)=ABS(GENG(35,M))
MZ(J,NRPM)=ABS(GENG(36,M))
ENDIF
ENDDO
ENDDO
IF(NRPM.EQ.11)THEN
DO J=1,6
DO N=1,NRPM
ESP=RPMIN+(N-1)*RPMI
EO=J*0.5
WRITE(*,*)ESP,EO,FX(J,N),FY(J,N),FZ(J,N),MX(J,N),MY(J,N),MZ(J,N)
ENDDO
ENDDO
ENDIF
|
|
|
Back to top |
|
|
colt1954
Joined: 21 Dec 2010 Posts: 81
|
Posted: Thu Mar 24, 2011 4:13 pm Post subject: Hi |
|
|
This problem was sorted by making the new set of arrays exactly the same size as the original set (in the array declaration, not shown above) even though the second set only needed a fraction of the first array data...not elegant I realise and I'm sure there must be a better way, but hey it worked. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Fri Mar 25, 2011 12:58 am Post subject: |
|
|
You appear to be searching for the closest value of THETA. An alternative approach could be:
1) Find the closest value of THETA (see code below) or,
2) Find the 2 closest values of THETA and do a linear interpolation between these two.
The simpler closest value search could be coded as:
Code: | DO J=1,6
!
! Find closest value of THETA to RPM*J/120
m = 2
DO I=3,512
IF (ABS(THETA(2,I)-(RPM*J/120.)).LT.ABS(THETA(2,M)-(RPM*J/120.))) M = I
END DO
!
! Adopt this M approximation
FX(J,NRPM)=ABS( dble(GENG(31,M)) )
FY(J,NRPM)=ABS( dble(GENG(32,M)) )
FZ(J,NRPM)=ABS( dble(GENG(33,M)) )
MX(J,NRPM)=ABS( dble(GENG(34,M)) )
MY(J,NRPM)=ABS( dble(GENG(35,M)) )
MZ(J,NRPM)=ABS( dble(GENG(36,M)) )
WRITE(*,*) RPM,FX(J,NRPM),FY(J,NRPM),FZ(J,NRPM),MX(J,NRPM),MY (J,NRPM),MZ(J,NRPM)
END DO
|
Your approach would fail if THETA differs by more than .001 from RPM*J/120
Also are RPM and THETA real ?
I would have a temporary real variable "RPM_J"
RPM_J = RPM * real(j) / 120.0
For your second loops, your first loops have only defined FX...MZ for N=NRPM; based on the code you have supplied.
DO N=1,NRPM
ESP=RPMIN+(N-1)*RPMI
EO=J*0.5
WRITE(*,*)ESP,EO,FX(J,N),FY(J,N),FZ(J,N),MX(J,N),MY(J,N),MZ(J,N)
ENDDO
It might only work if NRPM = 1
John |
|
Back to top |
|
|
colt1954
Joined: 21 Dec 2010 Posts: 81
|
Posted: Fri Mar 25, 2011 9:06 am Post subject: Hi John |
|
|
John, really appreciate your efforts...no the NRPM integer is called via a subroutine in stepwise fashion...after NRPM calls to subroutine NRPM=10 say, so the arrays are seeded with 10 sets of values etc thats when the second loop is invoked, so it does work. As I stated my problem was I had to make the array sizes equal which seems a waste of space...but hey with modern computers it does not seem to mind.
Your comments re. the If statement <0.001 well really that is more than accurate for what I'm doing its a simple sieve on quite distinct vibration order values so it good enough !! |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Sun Mar 27, 2011 12:38 pm Post subject: |
|
|
For your info, I thought I'd explain a way you could use linear interpolation from your table of values.
By allowing linear interpolation between values, the size of the look-up table can be much smaller.
This approach makes no assumption on the order of values in THETA(2,: ) Code: |
DO J=1,6
!
rpm_j = rpm*real(j)/120.
!
! Find two closest values of THETA to RPM*J/120
! this approach assumes all values of THETA(2,:) are different
! they are not required to be ordered
m1 = 0
do k = 1,2
m2 = 0
DO I=2,512
if (m1==i) cycle
if (m2==0) m2=i
IF (ABS(THETA(2,I)-rpm_j)) < ABS(THETA(2,M2)-rpm_j)) ) M2 = I
END DO
if (k==1) m1 = m2
END DO
!
! Define factors F1 and F2 for table values M1 and M2
! note: THETA(2,m2) - THETA(2,m1) must not be zero
! this assumes interpolation and not extrapolation.
f1 = abs ( (THETA(2,m2)-rpm_j) / (THETA(2,m2)-THETA(2,m1)) )
f2 = abs ( (THETA(2,m1)-rpm_j) / (THETA(2,m2)-THETA(2,m1)) )
ff = f1 + f2
f1 = f1 / ff
f2 = f2 / ff
!
! Adopt this linear approximation between M1 and M2
FX(J,NRPM) = ABS( f1*dble(GENG(31,M1)) + f2*dble(GENG(31,M2)) )
FY(J,NRPM) = ABS( f1*dble(GENG(32,M1)) + f2*dble(GENG(32,M2)) )
FZ(J,NRPM) = ABS( f1*dble(GENG(33,M1)) + f2*dble(GENG(33,M2)) )
MX(J,NRPM) = ABS( f1*dble(GENG(34,M1)) + f2*dble(GENG(34,M2)) )
MY(J,NRPM) = ABS( f1*dble(GENG(35,M1)) + f2*dble(GENG(35,M2)) )
MZ(J,NRPM) = ABS( f1*dble(GENG(36,M1)) + f2*dble(GENG(36,M2)) )
WRITE(*,*) RPM,FX(J,NRPM),FY(J,NRPM),FZ(J,NRPM),MX(J,NRPM),MY (J,NRPM),MZ(J,NRPM)
END DO
|
M1,M2,K are integer, while F1,F2,FF are real
John
ps: I didn't compile, but hopefully it works as coded. Should be easy to check. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Mar 28, 2011 12:54 am Post subject: |
|
|
Further to my last post, if THETA(2,: ) is ordered, then you can use linear interpolation for the values, using Code: | !
! If THETA(2,:) is ordered
DO M1=2,512
IF (THETA(2,M1) >= THETA(2,M1+1)) cycle
IF (THETA(2,M1) < rpm_j) EXIT
END DO
! Define factors F1 and F2 for table values M and M+1
M2 = M1+1
F1 = (theta(2,M2)-RPM_J) / (THETA(2,M2)-THETA(2,M1))
F2 = 1.0 - F1
! |
It is interesting to see the difference between the two approaches if, for unusual values of THETA and rpm_i is not between theta(m1) and theta(m2). ( This occurs if the values of theta are not evenly spaced). The following program calculates the extrapolation of a simple linear function Code: | integer*4 i
real*4 x,y,ff,f1,f2,a1,a2, x1,x2,y1,y2
!
x1 = 20
x2 = 30
y1 = 20
y2 = 30
!
do i = 1,50
x = i
!
! Weighted interpolation from two closest values
f1 = abs ( (x2-x) / (x2 - x1) )
f2 = abs ( (x1-x) / (x2 - x1) )
ff = f1 + f2
a1 = f1 / ff
a2 = f2 / ff
y = a1*y1+a2*y2
!
! linear extrapolation from two values
write (*,*) ' weight', x, f1, f2, a1, a2, y
f2 = (x-x1)/(x2-x1)
f1 = 1 - f2
a1 = f1
a2 = f2
y = a1*y1+a2*y2
write (*,*) ' linear', x, f1, f2, a1, a2, y
end do
end
|
If you plot the values of y from the 2 approaches, you get the difference between weighted average and linear extrapolation, for x outside 20:30.
It's an interesting difference, depending on your interpretation of THETA and GENG.
The other important outcome is you can have much fewer values in your look up table if GENG varies near linearly with THETA.
Also, a 3 or 4 point interpolation can be used for quatratic interpolation, if GENG has uniform non-linear variation, using a much smaller table, resulting in a more accurate estimation of the value. Google Bessel 4 point interpolation or Newton 3 point interpolation. The downside of higher order estimates is any error in your table values is amplified by the higher order approach, so values of GENG obtained from experiments can produce interesting results.
John |
|
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
|