In the following function using xtensor, I was expecting the compiler to express the computation graph to auto z = 3.0 * u + 100 * xt::cos(u); and evaluate the result at xt::xtensor_fixed<T, xt::xshape<nn>> out = z; when assigning the expression to an exact tensor.
template<typename T, size_t nn>
T func_cos(xt::xtensor_fixed<T, xt::xshape<nn>> &u) {
auto z = 3.0 * u;
for (auto k = 0; k < 100; ++k){
z += xt::cos(u);
}
xt::xtensor_fixed<T, xt::xshape<nn>> out = z;
return out(0);
}
However, I got an error
views_xtensor.cpp:76:11: error: no viable overloaded '+='
z += xt::cos(u);
[....]
Did I use auto in an wrong way? How could I use lazy evaluation in a for-loop?
Thank you for your help!
When you write
auto z = 3.0 * u
The type of z encodes the operation, it is something like
xfunction<multiplies, scalar<double>, xtensor_fixed>
This class does not hold any value, so it is not possible to assign it anything (even if it is a computed assignment). Now even if iw was possible, consider the following expression
auto y = z + xt::cos(u);
The type of this expression is something like
xfunction<plus, type(z), xfunction<cos, xtensor_fixed>>
So when you write
z += xt::cos(u); // equivalent to z = z + xt::cos(u);
You try to assign z something of a completely different type.
Lazy evaluation cannot be used in for loops for these reasons.
Related
I have a doubt about this code:
int i, x, z = 4, y = 1;
i = x = z += y++;
Which is the value of i? Can we know that value or not?
First of all, have you tested if this compiles at all?
If not, then why?
Unless you write some code that invokes UB, compiler, regarding basic syntax of the language, has most of the answers you'll ever need. Please test it yourself, and if it's still not clear, or behaves weirdly, then it's something worth asking.
In this case, it's valid, so let's go through it.
#include <iostream>
int main() {
int i, x, z = 4, y = 1;
i = x = z += y++;
std::cout << "i=" << i << std::endl;
}
I compiled, ran it, and here's the result:
$ g++ test.cpp -o test
$ ./test
i=5
So, what is actually going on in this line?
i = x = z += y++;
First of all, it's easier to understand when you add parentheses so it's perfectly obvious what is evaluated and when:
i = (x = (z += (y++)));
i is a result of assignment to x;
x is a result of addition assignment to z;
z is a result of z + (y post increment);
You can then work your way backwards through the list, and will arrive at the correct result:
y++ evaluates to simply y, because post increment affects only value of y, not the result of expression itself;
z is then z + y, which is 4 + 1, or 5;
intermediate expression becomes i = x = z; (or, form that's too obvious, i = (x = z);), and that means that i, just like x is 5.
Whatever you do, please don't actually write code like this, while it's easy to deconstruct, it's not something that is easy to understand at a first glance, and that, more often than not, causes confusion.
Can we know that value or not?
Yes.
Which is the value of i?
5
since you add y to i, where their values are 4 (since i gets assigned the value of z, which is 4) and 1 respectively.
y is incremented after z has been initialized. It's incremented in the following statement, as #john commented.
As #LightnessInOrbit commented, this is not good code. Forget about it and move on.
Yes the value of i is 5.
Just trace the code.
y++ post increement i,e first assign the value then increement so Y= 4. Next
z += y shorthand operation i,e.., z= z + y ,initially z=4 so 5 = 4+ 1 so Z=5
x = z i.e, x = 5 Next
i = x i.e, i = 5.
I have the following code:
type point = { x : float; y : float; z : float }
type dpoint = { dx : float; dy : float; dz : float }
type physical_object = { position : point; velocity : dpoint }
let move p dp = {x = p.x + dp.x; y = p.y + dp.y; z = p.z + dp.z}
I am getting this error:
File "code.ml", line 4, characters 21-24:
Error: This expression has type float but an expression was expected of type
int
p.x is highlighted
Why is this?
Am I not referencing the record's fields correctly?
Operator + has type int -> int -> int and thus is applicable only for the values of type int. Use +. operator for floats, (and *., /. correspondingly for other operations).
OCaml doesn't have operator overloading (aka ad hoc polymorphism), as it doesn't play well with type inference. However, it makes your code much more explicit, that can be considered a benefit.
In OCaml, + works on integers only. For floats you have to use the +. operator (that's with a dot suffix). For more details, see e.g. http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html.
I am using Rcpp to integrate a piece of C++ code in R. I am implementing a function in C++ in two ways:
// [[Rcpp::export]]
double rhobiweight(double x,double k = 2.0){
double rho = 1.0;
if(abs(x)<k){
rho = 1.0-pow((1.0-pow(x/k,2)),3);
}
return rho/Erho(k) ;
}
// [[Rcpp::export]]
double rhobiweight2(double x,double k = 2.0){
double rho = 1.0-pow((1.0-pow(x/k,2)),3);
if(abs(x)>k){
rho = 1.0;
}
return rho/Erho(k) ;
}
If the x-value is between 2 and 3, I get different results of these functions. I can't figure out why.
> set.seed(1)
> x = 3*rnorm(10^5)
> c = x
> c2 = x
> for(i in 1:length(x)){
+ c[i] = rhobiweight(x[i])
+ c2[i] = rhobiweight2(x[i])
+ }
> print(sum(c-c2))
[1] -18564.31
The problem comes from your if statement inside the function. The negative of < is >=. so you should either replace < with <= in one function or > with >= in the other, depending on the expected behaviour.
Your problem happens for value between 2.0 and 2.9 inclusive because the abs(int) will always return 2 for this range.
abs(x) takes an int an return an int. Your double x is implicitly conversion to an int in your case.
I am wondering a bit about the ternary operator mainly in C++ but I think it might apply for other languages as well.
The best example of the problem I am having, (or should I call it a problem? Well a conceptual problem I guess.), would be clamping values.
float clamped = (x<0.3) : 0.3 ? x;
I find myself wanting to write this piece of code, however x might be complex say we have something like this:
float clamped = (1.f - x + my_function()) > .2f ? .2f : (1.f - x + my_function());
This is where it's out of hand in my opinion and I would rewrite it:
float clamped = (1.f - x + my_function());
if (clamped > .2f)
clamped = .2f;
So this leads up to two questions really
1: Is there a defaulting behavior so I could say "do this if true, else just do what it said", in pseudo-code something like: float clamped = (1.f - x + my_function()) > .2f : .2f ? **default**;
2: If I would still do it the first way, will it first evaluate the condition, and if it is false, do another evaluation to get the value from (1.f - x + my_function())?
Hope some of it makes sense, it's something which I haven't gotten around to understand until now.
You can use the max function for this:
float clamped = max(1.f - x + my_function(), .2f);
How about
float v;
float processed = (v = expr) > 0.f ? special_val : v;
?
Or more generically
type tmp;
type result = condition(tmp = expr) ? special_val : tmp;
This is something that's I've wanted to know recently, mostly out of curiousity. I'm in the mood to learn some old coding styles, and FORTRAN seems like a good place to start.
I guess I should help you guys out by providing a good starting point.
So how would this C procedure be written in FORTRAN?
int foo ( int x , int y )
{
int tempX = x ;
x += y / 2 ;
y -= tempX * 3 ; // tempX holds x's original value.
return x * y ;
}
I know the entire function could be a single line:
return ( x + ( y / 2 ) ) * ( y - ( x * 3 ) ) ;
But the point of me asking this question is to see how those four statements would be written individually in FORTRAN, not neccessarily combined into a single statement.
Don't blame me - you said old coding styles:
C234567
SUBROUTINE FOO(I,J,K)
C SAVE THE ORIGINAL VALUES
IORIG = I
JORIG = J
C PERFORM THE COMPUTATION
I = I + J/2
J = J - IORIG*3
K = I * J
C RESTORE VALUES
I = IORIG
J = JORIG
END SUBROUTINE FOO
I shudder as I write this, but
all variables are implicitly integers, since they start with letters between I and N
FORTRAN passes by reference, so reset I and J at the end to give the same effect as the original function (i.e. pass-by-value, so x and y were unchanged in the calling routine)
Comments start in column 1, actual statements start in column 7
Please, please, please never write new code like this unless as a joke.
Your function might look like this in Fortran
integer function foo(m, n)
integer i
i = m
m = m + n/2
n = n - i*3
foo = m*n
end function foo
You should be able to get started with any tutorial on Fortran. Some thing like this might help http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/fortran.html
cheers
See Functions and Subroutines:
INTEGER FUNCTION foo(i, j)
...
foo = 42
END
then later:
k = foo(1, 2)
Where do you learn FORTRAN from? Just take a look at the wikibooks!
Derived from the example, I'd say:
function func(x, y) result(r)
integer, intent(in) :: x, y
integer :: r
integer :: tempX
tempX = x
x = x / 2
y = y - tempX * 3
r = x * y
end function foo
Similar to above, but with a main program to illustrate how it would be called.
C2345678
program testfoo
implicit none
integer r, foo
r = foo(4,5)
print *, 'result = ', r
end
integer function foo(x,y)
integer x, y
integer tx, ty
tx = x + y / 2
ty = y - x * 3
foo = tx * ty
return
end
Note that this is Fortran 77, which is what I learned 23 years ago.
True old style in applying the rule IJKLMN for integer
C2345678
FUNCTION IFOO(I,J)
II = I + J/2
JJ = J - I*3
IFOO = II*JJ
END