Reading binary file using IDL - binaryfiles

I have a IDL program which reads data from binary file. I am a newbie in IDL and so I can't help with a few lines in the program. Any help would be appreciated.
'''
PRO READTHREEDIMENSIONAL,VAR,singlefname,NX,NY,NZ
; DECLARE VARIABLES
VAR = {NX:0L,NY:0L,NZ:0L}
VAR.NX = NX
VAR.NY = NY
VAR.NZ = NZ
rread = DBLARR(VAR.NX)
phiread = DBLARR(VAR.NY)
NCOSYSread = -1L
'''
What is the meaning of:
1) NX:0L
2) NCOSYSread = -1L

The NX:0L defines a long integer field NX in the VAR structure.
The NCOSYSread = -1L line defines a variable a long integer variable NCOSYSread that presumably would be used to read into via READU or READF later in this code.

Related

How to implement Bit Flags in VBScript

Ok, two disclaimers,
I do not work in Vbscript but need to use it a little for an HMI project
I am looking at doing this because this application limits total "tags" or variables
So basically what I am trying to achieve is the following;
a unit8, foo, has the value 5 which is b00000101 now I would like to view this as 8 binary values a pseudocode way of doing this would be
IF foo AND b00000001 <> 0 THEN 'sudo read
.....
foo = foo OR b00000010 'sudo write 1
foo = foo AND b11111101 'sudo write 0
...ect
I think it will be something like
&foo AND &b00000001 <> 0
is this practical in VBScript again I am well aware this is not standard practice but in between tag limitations and HMI input limitations it might actually make the most sense in this application.
You could give something like this a try which uses Bitwise Operators to read and write the bitwise flags.
Function GetFlag(value, bit_num)
Dim bit_mask
If bit_num < 32 Then bit_mask = 2 ^ (bit_num - 1) Else bit_mask = "&H80000000"
GetFlag = CBool(value AND bit_mask)
End Function
Function SetFlag(value, bit_num, new_value)
Dim bit_mask
If bit_num < 32 Then bit_mask = 2 ^ (bit_num - 1) Else bit_mask = "&H80000000"
If new_value Then
SetFlag = value OR bit_mask
Else
bit_mask = NOT bit_mask
SetFlag = value AND bit_mask
End If
End Function
'Define constants to store the flags (maximum of 32)
Const FLAG_SUDOREAD = 1
Const FLAG_SUDOWRITEONE = 2
Const FLAG_SUDOWRITETWO = 3
'Set the flags
Dim options
options = SetFlag(options, FLAG_SUDOREAD, True)
options = SetFlag(options, FLAG_SUDOWRITEONE, False)
options = SetFlag(options, FLAG_SUDOWRITETWO, True)
'Read the flags
WScript.Echo "FLAG_SUDOREAD = " & GetFlag(options, FLAG_SUDOREAD)
WScript.Echo "FLAG_SUDOWRITEONE = " & GetFlag(options, FLAG_SUDOWRITEONE)
Output:
FLAG_SUDOREAD = True
FLAG_SUDOWRITEONE = False
Useful Links
Using Bitwise Operators In VB (Excellent resource for learning Bitwise operators and how to use them)

OpenMP parameter sweep parallel

I am new to OpenMP. I want to solve a stiff ODE system for a range of parameter values using parallel do loops. I use the following code in Fortran given below. However, I do not know whether calling a stiff solver(as a subroutine) inside a parallel do loop is allowed or not? Also, I want to write the time series data into files with filenames such as "r_value_s__value.txt" in the subroutine before the return to the main program. Can anyone help. Below is the code and the error. I used gfortran with flags -fopenmp to compile.
PROGRAM OPENMP_PARALLEL_STIFF
USE omp_lib
IMPLICIT NONE
INTEGER :: I, J
INTEGER, PARAMETER :: RTOT=10, STOT=15
INTEGER :: TID
INTEGER, PARAMETER :: NUM_THREADS=8
DOUBLE PRECISION :: T_INITIAL, T_FINAL
CALL OMP_SET_NUM_THREADS(NUM_THREADS)
CALL CPU_TIME(T_INITIAL)
PRINT*, "TIME INITIAL ",T_INITIAL
!$OMP PARALLEL DO PRIVATE(I,J,TID)
DO I=1,RTOT
DO J=1,STOT
TID=OMP_GET_THREAD_NUM()
CALL STIFF_DRIVER(TID,I,J,RTOT,STOT)
END DO
END DO
!$OMP END PARALLEL DO
CALL CPU_TIME(T_FINAL)
PRINT*, "TIME FINAL ",T_FINAL
PRINT*, "TIME ELAPSED ",(T_FINAL-T_INITIAL)/NUM_THREADS
END PROGRAM OPENMP_PARALLEL_STIFF
SUBROUTINE STIFF_DRIVER(TID,II,JJ,RTOT,STOT)
USE USEFUL_PARAMETERS_N_FUNC
USE DVODE_F90_M
! Type declarations:
IMPLICIT NONE
! Number of odes for the problem:
INTEGER :: SERIAL_NUMBER, TID
INTEGER :: II, JJ, RTOT, STOT, IND
INTEGER :: J, NTOUT
INTEGER :: ITASK, ISTATE, ISTATS, I
! parameters : declaration
DOUBLE PRECISION, PARAMETER :: s0=0.450D0, dr=1.0D-4, ds=1.0D-2
DOUBLE PRECISION, DIMENSION(NEQ) :: Y, YOUT
DOUBLE PRECISION :: ATOL, RTOL, RSTATS, T, TOUT, EPS, TFINAL, DELTAT
DIMENSION :: RSTATS(22), ISTATS(31)
DOUBLE PRECISION :: bb, cc, ba, ba1, eta
CHARACTER(len=45) :: filename
TYPE (VODE_OPTS) :: OPTIONS
SERIAL_NUMBER=3011+II+(JJ-1)*RTOT
IND=TID+3011+II+(JJ-1)*RTOT
WRITE (*,12)SERIAL_NUMBER,TID
12 FORMAT ("SL. NO. ",I5," THREAD NO.",I3)
r=(II-1)*dr
s=s0+JJ*ds
EPS = 1.0D-9
! Open the output file:
WRITE (filename,93)r,s
93 FORMAT ("r_",f6.4,"_s_",f4.2,".txt")
OPEN (UNIT=IND,FILE=filename,STATUS='UNKNOWN',ACTION='WRITE')
! Parameters for the stiff ODE system
q0 = 0.60D0; v = 3.0D0
Va = 20.0D-4; Vs = 1.0D-1
e1 = 1.0D-1; e2 = 1.10D-5; e3 = 2.3D-3; e4=3.0D-4
del = 1.7D-4; mu = 5.9D-4
al = 1.70D-4; be = 8.9D-4; ga = 2.5D-1
! S and r dependent parameters
e1s = e1/s; e2s = e2/(s**2); e3s = e3/s; e4s = e4/s
dels = del*s; rs = r*s
e1v = e1/v; e2v = e2/(v**2); e3v = e3/v; e4v = e4/v
delv = del*v; rv = r*v
! SET INITIAL PARAMETERS for INTEGRATION ROUTINES
T = 0.0D0
TFINAL = 200.0D0
DELTAT = 0.10D0
NTOUT = INT(TFINAL/DELTAT)
RTOL = EPS
ATOL = EPS
ITASK = 1
ISTATE = 1
! Set the initial conditions: USING MODULE USEFUL_PARAMETERS_N_FUNC
CALL Y_INITIAL(NEQ,Y)
! Set the VODE_F90 options:
OPTIONS = SET_OPTS(DENSE_J=.TRUE.,USER_SUPPLIED_JACOBIAN=.FALSE., &
RELERR=RTOL,ABSERR=ATOL,MXSTEP=100000)
! Integration:
DO I=1,NTOUT
TOUT = (I-1)*DELTAT
CALL DVODE_F90(F_FUNC,NEQ,Y,T,TOUT,ITASK,ISTATE,OPTIONS)
! Stop the integration in case of an error
IF (ISTATE<0) THEN
WRITE (*,*)"ISTATE ", ISTATE
STOP
END IF
! WRITE DATA TO FILE
WRITE (IND,*) TOUT,T, Y(NEQ-2)
END DO
CLOSE(UNIT=IND)
RETURN
END SUBROUTINE STIFF_DRIVER
At line ** of file openmp_parallel_stiff.f90 (unit = 3013)
Fortran runtime error: File already opened in another unit
The issue is the format that you chose: f6.4 for r will overflow for r>=10. Then, the output will be six asterisks ****** (depending on the compiler) for all values of r>=10 on all threads. The same holds true for s.
I would suggest to either limit/check the range of these values or extend the format to honor more digits.
As #francescalus mentioned, another possibility is hit a combination of II and JJ where r and s are identical.
Just for the fun of it - let's do the math:
r=(II-1)*dr
s=s0+JJ*ds
From r=s follows
(II-1)*dr = s0+JJ*ds
or
II = 1 + s0/dr + JJ*ds/dr
Using the constants s0=0.450D0, dr=1.0D-4, ds=1.0D-2 yields
II = 4501 + JJ*10
So, whenever this combination is true for two (or more) threads at a time, you run into the observed issue.
Simple solution for this case: add the thread number to the file name.

Why does my julia code run so slowly?

redim = 2;
# Loading data
iris_data = readdlm("iris_data.csv");
iris_target = readdlm("iris_target.csv");
# Center data
iris_data = broadcast(-, iris_data, mean(iris_data, 1));
n_data, n_dim = size(iris_data);
Sw = zeros(n_dim, n_dim);
Sb = zeros(n_dim, n_dim);
C = cov(iris_data);
classes = unique(iris_target);
for i=1:length(classes)
index = find(x -> x==classes[i], iris_target);
d = iris_data[index,:];
classcov = cov(d);
Sw += length(index) / n_data .* classcov;
end
Sb = C - Sw;
evals, evecs = eig(Sw, Sb);
w = evecs[:,1:redim];
new_data = iris_data * w;
This code just does LDA (linear discriminant analysis) for the iris_data.
Reduct the dimensions of the iris_data to 2.
It will takes about 4 seconds, but Python(numpy/scipy) only takes about 0.6 seconds.
Why?
This is from the first page, second paragraph of the introduction in the Julia Manual:
Because Julia’s compiler is different from the interpreters used for languages like Python or R, you may find that Julia’s performance is unintuitive at first. If you find that something is slow, we highly recommend reading through the Performance Tips section before trying anything else. Once you understand how Julia works, it’s easy to write code that’s nearly as fast as C.
Excerpt:
Avoid global variables
A global variable might have its value, and therefore its type, change at any point. This makes it difficult for the compiler to optimize code using global variables. Variables should be local, or passed as arguments to functions, whenever possible.
Any code that is performance critical or being benchmarked should be inside a function.
We find that global names are frequently constants, and declaring them as such greatly improves performance
Knowing that the script (all procedural top level code) style is so pervasive among many scientific computing users, I would recommend you to at least wrap the whole file inside a let expression for starters (let introduces a new local scope), ie:
let
redim = 2
# Loading data
iris_data = readdlm("iris_data.csv")
iris_target = readdlm("iris_target.csv")
# Center data
iris_data = broadcast(-, iris_data, mean(iris_data, 1))
n_data, n_dim = size(iris_data)
Sw = zeros(n_dim, n_dim)
Sb = zeros(n_dim, n_dim)
C = cov(iris_data)
classes = unique(iris_target)
for i=1:length(classes)
index = find(x -> x==classes[i], iris_target)
d = iris_data[index,:]
classcov = cov(d)
Sw += length(index) / n_data .* classcov
end
Sb = C - Sw
evals, evecs = eig(Sw, Sb)
w = evecs[:,1:redim]
new_data = iris_data * w
end
But I would also urge you to refactor that into small functions and then compose a main function that calls the rest, something like this, notice how this refactor makes your code general and reusable (and fast):
module LinearDiscriminantAnalysis
export load_data, center_data
"Returns data and target Matrices."
load_data(data_path, target_path) = (readdlm(data_path), readdlm(target_path))
function center_data(data, target)
data = broadcast(-, data, mean(data, 1))
n_data, n_dim = size(data)
Sw = zeros(n_dim, n_dim)
Sb = zeros(n_dim, n_dim)
C = cov(data)
classes = unique(target)
for i=1:length(classes)
index = find(x -> x==classes[i], target)
d = data[index,:]
classcov = cov(d)
Sw += length(index) / n_data .* classcov
end
Sb = C - Sw
evals, evecs = eig(Sw, Sb)
redim = 2
w = evecs[:,1:redim]
return data * w
end
end
using LinearDiscriminantAnalysis
function main()
iris_data, iris_target = load_data("iris_data.csv", "iris_target.csv")
result = center_data(iris_data, iris_target)
#show result
end
main()
Notes:
You don't need all those semicolons.
anonymous functions are currently slow but that will change in v0.5. You can use FastAnonymous for now, if performance is critical.
In summary read carefully and take into account all the performance tips.
main is just a name, it could be anything else you like.

How to Initialize Variable to Maximum Value

I am trying to figure out how to initialize a variable in VBScript to its maximum value.
For example, in C++, I would do something like:
double x = MAX_DOUBLE;
I am not sure how to do this in VBScript.
UPDATE
For now, I have defined the variable myself as constant value in the global scope of the script. I am not sure if this is the most elegant way of doing this. Is there a built-in variable I can use?
Const MAX_DOUBLE = CDbl(1.79769313486232e307)
Const MIN_DOUBLE = CDbl(-1.79769313486232e307)
I've never found the limits described on MSDN to be accurate for many of the VBScript data types. For example, the Currency type gives me an overflow for anything > XXX.5625, even though the docs say it should go to XXX.5808. Same thing for Double. The docs say the max should be 1.79769313486232e308 but that final 2 in the mantissa causes an overflow. These are the values I've used in the past:
Const MIN_BYTE = 0
Const MAX_BYTE = 255
Const MIN_INTEGER = -32768
Const MAX_INTEGER = 32767
Const MIN_LONG = -2147483648
Const MAX_LONG = 2147483647
Const MIN_SINGLE = -3.402823e38
Const MAX_SINGLE = 3.402823e38
Const MIN_DOUBLE = -1.79769313486231e308
Const MAX_DOUBLE = 1.79769313486231e308
Const MIN_CURRENCY = -922337203685477.5625
Const MAX_CURRENCY = 922337203685477.5625
Const MIN_DATE = #100/1/1#
Const MAX_DATE = #9999/12/31#
Because VBScript uses Variants, however, note that you may not get the type you expect when assigning a "max" (or min) value to a variable. For example:
b = MAX_BYTE ' Actually type Integer
s = MAX_SINGLE ' Actually type Double
c = MAX_CURRENCY ' Actually type Double
If you want to ensure you're getting the proper data type in return, you'll need to explicitly cast:
b = CByte(MAX_BYTE) ' Type Byte
s = CSng(MAX_SINGLE) ' Type Single
c = CCur(MAX_CURRENCY) ' Type Currency

Converting Decimal to ASCII Character

I am trying to convert an decimal number to it's character equivalent. For example:
int j = 65 // The character equivalent would be 'A'.
Sorry, forgot to specify the language. I thought I did. I am using the Cocoa/Object-C. It is really frustrating. I have tried the following but it is still not converting correctly.
char_num1 = [working_text characterAtIndex:i]; // value = 65
char_num2 = [working_text characterAtIndex:i+1]; // value = 75
char_num3 = char_num1 + char_num2; // value = 140
char_str1 = [NSString stringWithFormat:#"%c",char_num3]; // mapped value = 229
char_str2 = [char_str2 stringByAppendingString:char_str1];
When char_num1 and char_num2 are added, I get the new ascii decimal value. However, when I try to convert the new decimal value to a character, I do not get the character that is mapped to char_num3.
Convert a character to a number in C:
int j = 'A';
Convert a number to a character in C:
char ch = 65;
Convert a character to a number in python:
j = ord('A')
Convert a number to a character in Python:
ch = chr(65)
Most languages have a 'char' function, so it would be Char(j)
I'm not sure what language you're asking about. In Java, this works:
int a = 'a';
It's quite often done with "chr" or "char", but some indication of the language / platform would be useful :-)
string k = Chr(j);

Resources