Is there a way where I can assign the same value for different variables without constructing an array in a single statement?
For example, if I have variables a,b,c,d, and e, can I assign something like
a=b=c=d=e=10.0
?
I know that I can do in a single line:
a=10.0; b=10.0; c=10.0; d=10.0; e=10.0
But that is not I want since if I want to change the value 10.0 later to something else, I have to make the change everywhere.
The first version is not possible in Fortran. Following the (2008) Standard, an assignment is of the general form (ch. 7.2.1.1)
variable = expr
But why don't you try something like:
a=10.0; b=a; c=a; d=a; e=a
That way, you just need to change the value of a later on!
Come on Fortranners, you know you want to ...
equivalence(a,b,c,d,e)
Now all those rascals are going to have the same value at all times.
Perhaps:
real, parameter :: NamedConst = 10.0
a=NamedConst; b=NamedConst; c=NamedConst; d=NamedConst; e=NamedConst
Then if you should use the special value NamedConst in more than one line, there is clearly a single place to change its value.
You probably should consider to use an array instead of individual variables, especially if they serve similar purposes:
real :: myarray(5)
myarray(:) = 10.0
Related
I haven't been coding C++ long enough to know what is a good way to do this, so any and all advice is appreciated.
The vector is a list of option names, types, and values. It is hardcoded to allow for sensible values without any user specification, and as a fallback for when user's option file is missing or etc.
I would like to assign the entire vector to a public member variable of another object in a different class. The options don't necessarily need to be in a class; i'd be happy with a namespace. Ideally I would like to assign the entire vector with one large initialization, like
vec = {
{ name1, val1, ... },
.
.
.
{ nameN, valN, ... }
};
but a bunch of push_back()s would be ok too. After initialization i will read the options file and overwrite values as they are encountered.
Associated with this vector will be 3 functions: 1) Search for option by name, which will be used by 2) return integer value and 3) return string value. (Edit: no option will have both an int and a string value.)
Ultimately none of these ideas are set in concrete so if anybody has other thoughts I would be happy to hear them.
see "resolution" in above comments
I want to create a dynamic variable name using Fortran.
The variable name will be obtained by concatenating a string and another string/integer. Then I want to use this variable name to store a value or another variable.
e.g.
! assign values to 2 variables
my_string = h
my_integer = 1
! perform concatenation resulting in the dynamic variable name, h1
! Set the value of variable h1 to another integer value
h1 = 5
I fear that you will not be able to do this. Fortran requires that variables have names and types at compile time. You (or other SOers) may come up with some kludge to simulate what you want, but it will be a kludge.
Why do you want to do this in Fortran ? There are plenty of languages around which do permit this sort of variable declaration.
EDIT
Well, I thought about it some more, and here's a kludge, unfinished. First a UDT for 'dynamic' variables:
type dynamic_var
character(len=:), allocatable :: label
class(*), allocatable :: value
end type
declare some space for such variables:
type(dynamic_var), dimension(:), allocatable :: run_time_vars
and, working with your original data
allocate(run_time_vars(10)) ! No error checking, reallocate if necessary
! lots of code
write(run_time_vars(1)%label,'(a1,i1)') my_string, my_integer
allocate(run_time_vars(1)%value, source = my_value)
This compiles, but doesn't run and I'm not going to stay long enough to fix it, I'll leave that as an exercise to anyone who cares.
The write to the label field isn't right.
The sourced allocation to the value field doesn't seem to work correctly. Might need to write a 'decode' function to use like this:
allocate(run_time_vars(1)%value, source = decode(my_value))
Like I said, it's a kludge.
I think you want to use a data structure. If you have pairs or groups of values that go together, then create a derived data type which can hold both. There's an explanation on this page:
http://web.mse.uiuc.edu/courses/mse485/comp_info/derived.html
If you have a list of these pairs (like your string and int above), then you can create an array of these types. Example code below taken from the page linked above:
type mytype
integer:: i
real*8 :: a(3)
end type mytype
type (mytype) var
Array:
type (mytype) stuff(3)
var%i = 3
var%a(1) = 4.0d0
stuff(1)%a(2) = 8.0d0
An significant benefit of doing this is that you can pass the pairs/groups of items to functions/subroutines together. This is an important programming principle called Encapsulation, and is used extensively in the Object Oriented programming paradigm.
No, this is not possible in Fortran.
For more information, look into Reflection (computer programming).
Clearly, for reasons given above, this is not legit Fortran (and thus you're going into trouble ...). You may use smart (congrats guys!) kludges, but ...
Instead of using variables h concatenated with 1, 2 or whatever number, why not creating array h(1:N) where N does not have to be known at compilation time : you just have to declare array h as a allocatable.
This is, I think, the legit way in Fortran 90+.
The following code has to check for an 'e' value such that the gcd(h,e)=1. Where 1
module great(p,q,e,d);
input p,q;
output e,d;
reg e,d;
h=((p-1)*(q-1));
always
begin
for(e=2;e<h;e=e+1)
begin
g1=gcd(h,e);
if(g1==1)
return e;
If, by "return a value", you mean spit out a value you can use in another module, you would use the output of this module as your "return" value. But even ignoring the return e, I don't think your code will work if you tried to run it, because it is too much like a programming language. There's several major things wrong:
You already declared output e,d so you can't declare two reg with the same name. You probably want output reg e,d instead.
You didn't declare a type for h or g1.
You have a for loop for e but e can never be anything other than 0 or 1 because you didn't set a size for it, so by default it is only 1-bit long. Even if it was big enough that you could increment it past 1, it's a wire type by default, and you can't make those kind of increments to a wire directly.
I assume gcd is some module you made somewhere else, but this isn't how you interconnect modules together. You can't call it like it's a function. You have to use wire and reg to connect the inputs and outputs of two modules together, almost like you're plugging components in.
Those are what stick out the most to me, anyway. I think you are coding your Verilog as if it were Python and that's what's causing these misunderstandings. Verilog is very, very different.
Hi I am new here and want to solve this problem:
do k=1,31
Data H(1,k)/0/
End do
do l=1,21
Data H(l,1)/0.5*(l-1)/
End do
do m=31,41
Data H(17,m)/0/
End do
do n=17,21
Data H(n,41)/0.5*(n-17)/
End do
I get error for l and n saying that it is a syntax error in DATA statement. Anyone know how to solve this problem?
You have three problems here, and not just with the "l" and "n" loops.
The first problem is that the values in a data statement cannot be arbitrary expressions. In particular, they must be constants; 0.5*(l-1) is not a constant.
The second problem is that the bounds in the object lists must also be constant (expressions); l is not a constant expression.
For the first, it's also worth noting that * in a data value list has a special meaning, and it isn't the multiplication operator. * gives a repeat count, and a repeat count of 0.5 is not valid.
You can fix the second point quite simply, by using such constructions as
data H(1,1:31) /31*0./ ! Note the repeat count specifier
outside a loop, or using an implied loop
data (H(1,k),k=1,31) /31*0./
To do something for the "l" loop is more tedious
data H(1:21,1) /0., 0.5, 1., 1.5, ... /
and we have to be very careful about the number of values specified. This cannot be dynamic.
The third problem is that you cannot specify explicit initialization for an element more than once. Look at your first two loops: if this worked you'd be initializing H(1,1) twice. Even though the same value is given, this is still invalid.
Well, actually you have four problems. The fourth is related to the point about dynamic number of values. You probably don't want to be doing explicit initialization. Whilst it's possible to do what it looks like you want to do, just use assignment where these restrictions don't apply.
do l=1,21
H(l,1) = 0.5*(l-1)
End do
Yes, there are times when complicated explicit initialization is a desirable thing, but in this case, in what I assume is new code, keeping things simple is good. An "initialization" portion of your code which does the assignments is far more "modern".
set var1 A
set var2 {A}
Is it possible to check if variable is list in TCL? For var1 and var2 llength gives 1. I am thinking that these 2 variables are considered same. They are both lists with 1 element. Am I right?
Those two things are considered to be entirely identical, and will produce identical bytecode (except for any byte offsets used for indicating where the content of constants are location, which is not information normally exposed to scripts at all so you can ignore it, plus the obvious differences due to variable names). Semantically, braces are a quoting mechanism and not an indicator of a list (or a script, or …)
You need to write your code to not assume that it can look things up by inspecting the type of a value. The type of 123 could be many different things, such as an integer, a list (of length 1), a unicode string or a command name. Tcl's semantics are based on you not asking what the type of a value is, but rather just using commands and having them coerce the values to the right type as required. Tcl's different to many other languages in this regard.
Because of this different approach, it's not easy to answer questions about this in general: the answers get too long with all the different possible cases to be considered in general yet most of it will be irrelevant to what you're really seeking to do. Ask about something specific though, and we'll be able to tell you much more easily.
You can try string is list $var1 but that will accept both of these forms - it will only return false on something that can't syntactically be interpreted as a list, eg. because there is an unmatched bracket like "aa { bb".