Fortran - Usage of Variables - fortran

Once compiled, is there any difference in execution speed/efficiency to using an extra variable to reference some part of an array versus continually indexing it? For example:
... some code that defines/populates "array" here ...
item3 = array(3)
subroutine1(item3, ...)
...
subroutine2(item3, ...)
...
some equation using item3
...
subroutine3(item3, ...)
... etc
versus
... some code that defines/populates "array" here ...
subroutine1(array(3), ...)
...
subroutine2(array(3), ...)
...
some equation using array(3)
...
subroutine3(array(3), ...)
... etc
Another example might be creating a variable that could just be skipped. For example:
x = b / c
y = x + 1 ! This is the only use of x
vs
y = (b / c) + 1
Would these be equivalent when compiled, or would the first one be slower due to creating that variable "x"? If you needed that value of "x" many times, then I assume the first would be quicker then since it would avoid doing the division many times. But for only 1 or 2 uses, I'm not sure.

Related

Is there a way to set up an app to solve equations and then compare them in C++?

I am trying to write a piece of code for my old Highschool teacher for a game he had us play literally called the "Dice Game." Let's just say that the game takes two d12's and multiplies them together to get a number (D) in this instance. Then you take 3 d6's and roll them to get your A, B, and C variables. You would then either Add, Subtract, Multiply, Divide, Exponentiate, or Root by that number to get as close to as you could to D. Those operations would stand for x and y in the following equation
AxByC=D
I don't know how else to word this, but I am having trouble finding any way to solve these equations and then compare them. Maybe I am missing something simple, but I don't know.
EDIT: I should probably be more clear about the question. I know how to set all the equations up. It is just a matter of finding a way to compare the answers to the D variable and then the other answers to the equation to see which one is closer. The closest number to D wins, thus the whole point to the dice game.
If you are just trying to compare the answers to the D variable, why not loop through each equations result and compare them equal to D?
for (int i = 0; i < equationResults.size(); i++) {
if (equationResults[i] == D)
return true;
}
EDIT: If you are trying to find the closest to D, you can compare each answer to D and subtract the answer from D and store it, then return the min value:
closeToD[0] = D - equationResults[0];
return *min_element(closeToD.begin(), closeToD.end());
Since you can juggle the values around, as well as picking operators, you actually have two problems: generating the permutations of variables and generating the permutations of operators. The first part is rather straightforward:
std::array<int, 3> input;
std::sort(input.begin(), input.end());
do {
compute(input[0], input[1], input[2]);
} while (std::next_permutation(input.begin(), input.end()));
The compute part could be a function that takes such an array of 3 values and finds the best value, or closest to D, or just all values.
Generating all permutations of operators is slightly more annoying because next_permutation can't compare them, and also we accept duplicates. The easiest way is to just brute-force through them; I'll do it just for the slightly easier operators:
std::array<int, 16> compute(int a, int b, int c) {
return {
a + b + c,
a + b - c,
a + b * c,
a + b / c,
a - b + c,
a - b - c,
a - b * c,
a - b / c,
a * b + c,
a * b - c,
a * b * c,
a * b / c,
a / b + c,
a / b - c,
a / b * c,
a / b / c,
};
}
Generating such list of operations programmatically is a bit more challenging; you can't simply do (a op b) op c because of the aforementioned precedence. Doing it this way guarantees that the results are actually achievable because of the operator precedence built into the language.
This will still do redundant computations - e.g. in the first case, the result will be the same regardless of the permutation of a/b/c. Eliminating those is perhaps a more interesting exercise for later. Perhaps a small relief is the fact that if a == b or b == c, next_permutation will already take care of that for us, cutting the number of iterations from 6 to either 3 or 1.

Multiplying 1xn Eigen::Array with 2xn Eigen::Array, with each column in the 1xn array behaving like a scalar

I have two Eigen::Array which have the same number of columns. One of them, a, has one row, and the other, b, has two rows.
What I want to do, is to multiply every column of b with the entry in the respective column in a, so that it behaves like this:
ArrayXXd result;
result.resizeLike(b);
for (int i=0; i<a.cols(); ++i)
result.col(i) = a.col(i)[0] * b.col(i);
However, it's part of a rather long expression with several of such multiplications, and I don't want to have to evaluate intermediate results in temporaries. Therefore, I'd rather get an Eigen expression of the above, like
auto expr = a * b;
This, of course, triggers an assertion, because a.rows() != b.rows().
What I tried, which works, is:
auto expr = a.replicate(2,1) * b;
However, the resulting code is very slow, so I hope there's a better option.
Possibly related.
Eigen provides the possibility to use broadcasting for such cases. However, the one-dimensional array should first be converted into a Vector:
broadcasting operations can only be applied with an object of type Vector
This will work in your case:
RowVectorXd av = a;
ArrayXXd expr = b.rowwise() * av.array();
Edit
To avoid a copy of the data into a new vector one can use Map:
ArrayXXd expr = b.rowwise() * RowVectorXd::Map(&a(0), a.cols()).array();
I have posted the same solution to your previous question but here is my answer again:
Define your arrays with fixed number of rows but dynamic number of columns whereas ArrayXXd type yields an array with both dynamic number of rows and columns.
Use fixed-size version of operations. This should typically give faster code.

Cython replacing list of tuples by C equivalent

I am trying to speed up an already very optimized function in Cython using list of two sized tuples of doubles as inputs and outputs. To do that I need to have it all in pure C first.
In python somehow cythonized the tuple syntax ressembles this:
def f(inputList1, inputList2):
cdef double p, i10,i11,i20,i21,a0,a1
a0,a1=inputList1[-1]
for i10,i11 in inputList1:
outputList=[]
#some more computations involving a0 and a1
for i20,i21 in inputList2:
p=f(i10,i11,a0,a1,i21,i20) #f returns a double
if p==0:
outputList.append((i10,i21))
else if p>0:
outputList.append(g(i10,i21,i20,i21)) #g returns two outputs that are parsed as a two sized tuples automatically
if len(outputList)<1:
return []
#some more computations
a0, a1=i10, i11
return outputList
The details are not relevant what is important is the speed and the syntax: it uses tuple unpacking in the for loops to break the tuples apart and can append whole tuples using append(), it can also fetch the last element of a list and it can return an empty list. It can also convert the two outputs of g to a tuple.
I am trying to change all the python to pure C to either increase speed or at least not damage the speed in my mind it should be doable (maybe I am wrong ?). So as g has to become pure C g has to return one object (I guess multiple outputs are out of the question ?)
My first idea was to use std::vectors and std::pairs lists of lists become vector[pair[double,double]] I modified g to return a pair[double,double] instead of two doubles
cdef vector[pair[double,double]] f(vector[pair[double,double]] inputList1, vector[pair[double,double]] inputList2):
cdef double p, i10,i11,i20,i21,a0,a1
#I have to add the pairs as I cannot use the for a,b in syntax
cdef pair[double,double] i1,i2,e
cdef vector[pair[double,double]] outputList, emptyList
a0,a1=inputList.back()
for i1 in inputList1:
i10=i1.first
i11=i1.second
outputList=emptyList
#some more computations involving a0 and a1
for i2 in inputList2:
i20=i2.first
i21=i2.second
p=f(i10,i11,a0,a1,i21,i20) #f returns a double
if p==0.:
outputList.push_back(i1) #I am now using push_back and not append
else if p>0.:
outputList.push_back(g(i10,i21,i20,i21)) #g now returns a pair
if outputList.size()<1:
return outputList
#some more computations
a0, a1=i10, i11
return outputList
Everything is pure C but it is 3 times slower !!!
I also tried std::list and list[list[double]] I am losing in speed by a factor of 3 also ! I use i1.back() and i1.front() instead of first and second I guess that makes me loose speed too. What is the reason for that ? Is there a better C object to use ? Is is the syntax I am using ? Doing explicitely i20=i2.first and so on is that what makes it so slow ?
Especially the syntax of g now seems really silly maybe the bottleneck comes from there:
cdef pair[double,double] g(double a, double b, double c, double d):
#looks ugly that I have to define res
cdef pair[double,double] res
cdef double res_int
res_1=computations1(a,b,c,d)
res_2=computations2(a,b,c,d)
#looks ugly
res.first=res_1
res.second=res_2
return res
instead of simply returning res_1, res_2 as before:
EDIT: I redid everything to benchmark the different solutions and:
-it turns out the list[list[double]] is not an option for me because later in my code I need to access specific elements of the list through indexing
-vector[np.ndarray[DTYPE, ndim=1]] does not work I guess you cannot form a vector with Python objects
-vector[pair[double,double]] is actually indeed faster than Python list versions !
For 100000 iterations the Python version takes in total:
1.10413002968s for the Python version
0.781275987625s for the (vector[pair[double,double]]) C version.
It still looks very ugly and I still want to hear if this is the right approach

"Templated" functions for julia

I have a function that essentially acts as a look-up table:
function lookup(a::Int64, x::Float64, y::Float64)
if a == 1
z = 2*x + y
else if a == 2
z = 5*x - 2*y
else if a == 3
...
end
return z
end
The variable a essentially determines what the relation of z is.
This function however takes a while to compile and is also not the most efficient at run time.
Could you compile the function lookup only for one instance of a (say a=1)? It is unlikely that this function will called for all possible functions of a.
I believe that such a functionality would be similar to templated functions in C++.
Julia's compiler can only dispatch on the type of arguments, not their value, as the value is only known at runtime. You can cheat a little by creating a "value type", where different values of a variable act as a different type:
lookup(::Type{Val{1}}, x, y) = 2x+y
lookup(::Type{Val{2}}, x, y) = 5x-2y
a = 2
lookup(Val{a}, 2, 3)
# 4
If you want to use this approach, you should read https://docs.julialang.org/en/stable/manual/performance-tips/#Types-with-values-as-parameters-1 first, to make sure it does not create issues with type-stability.

CODE1 at SPOJ - cannot solve it

I am trying to solve the problem Secret Code on SPOJ, and it's obviously a math problem.
The full problem
For those who are lazy to go and read, it's like this:
a0, a1, a2, ..., an - sequence of N numbers
B - a Complex Number (has both real and imaginary components)
X = a0 + a1*B + a2*(B^2) + a3*(B^3) + ... + an*(B^n)
So if you are given B and X, you should find a0, a1, ..an.
I don't know how or where to start, because not even N is known, just X and B.
The problem is not as easy as expressing a number in a base B, because B is a complex number.
How can it be solved?
The key is that a0 .. an are not arbitrary numbers, they're integers (otherwise, this wouldn't be possible in general). You're given the number X , and are asked to express it in base B. Why don't you start by working a few examples for a specific value of B?
If I asked you to write 17 in base 2, would you be able to do that? Can you find a way to generalize the algorithm you use to bases other than 2?