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.
Related
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.
I am trying to implement steepest descent algorithm in programming languages (C/C++/fortran).
For example minimization of f(x1,x2) = x1^3 + x2^3 - 2*x1*x2
Estimate starting design point x0, iteration counter k0, convergence parameter tolerence = 0.1.
Say this staring point is (1,0)
Compute gradient of f(x1,x2) at the current point x(k) as grad(f). I will use numerical differentiation here.
d/dx1 (f) = lim (h->0) (f(x1+h,x2) - f(x1,x2) )/h
This is grad(f)=(3*x1^2 - 2*x2, 3*x2^2 - 2*x1)
grad(f) at (0,1) is c0 = (3,-2)
since L2 norm of c0 > tolerence, we proceed for next step
direction d0 = -c0 = (-3,2)
Calculate step size a. Minimize f(a) = f(x0 + ad0) = (1-3a,2a) = (1-3a)^3 + (2a)^3 - 2(1-3a)*(2a). I am not keeping constant step size.
update: new[x1,x2] = old[x1,x2]x + a*d0.
I do not understand how to do step 5.
I have a 1D minimization program with bisection method, and it looks like:
program main()
...
...
define upper, lower interval
call function value
...calculations
...
...
function value (input x1in) (output xout)
...function is x^4 - 2x^2 + x + 10
xout = (xin)^4 - 2*(xin)^2 + (xin) + 10
In this case, looking at step 5, I cannot pass symbolic a.
Any ideas how to implement the algorithm in programming language, especially step 5? Please suggest if there is altogether different way to program this. I have seen many programs with constant step size, but I want to compute it at every step. This algorithm can be easy to implement in MATLAB ot python sympy using symbolics, but I do not want to use symbolics.
Any suggestions appreciated. Thanks.
If C++ is an option, you can take advantage of functors and lambdas.
Let's consider a function we want to minimize, for example y = x2 - x + 2. It can be represented as a function object, which is a class with an overloaded operator():
struct MyFunc {
double operator()( double x ) const {
return x * x - x + 2.0;
}
};
Now we can declare an object of this type, use it like a function and pass it to other templated function as a templated parameter.
// given this templated function:
template < typename F >
void tabulate_function( F func, double a, double b, int steps ) {
// the functor ^^^^^^ is passed to the templated function
double step = (b - a) / (steps - 1);
std::cout << " x f(x)\n------------------------\n";
for ( int i = 0; i < steps; ++i ) {
double x = a + i * step,
fx = func(x);
// ^^^^^^^ call the operator() of the functor
std::cout << std::fixed << std::setw(8) << std::setprecision(3) << x
<< std::scientific << std::setw(16) << std::setprecision(5)
<< fx << '\n';
}
}
// we can use the previous functor like this:
MyFunc example;
tabulate_function(example, 0.0, 2.0, 21);
OP's function can be implemented (given an helper class to represent 2D points) in a similar way:
struct MyFuncVec {
double operator()( const Point &p ) const {
return p.x * p.x * p.x + p.y * p.y * p.y - 2.0 * p.x * p.y;
}
};
The gradient of that function can be represented (given a class which implement a 2D vector) by:
struct MyFuncGradient {
Vector operator()( const Point &p ) {
return Vector(3.0 * p.x * p.x - 2.0 * p.y, 3.0 * p.y * p.y - 2.0 * p.x);
}
};
Now, the fifth step of OP question requests to minimize the first function along the direction of the gradient using a monodimensional optimization algorithm which requires a monodimensional function to be passed. We can solve this issue using a lambda:
MyFuncVec funcOP;
MyFuncGradient grad_funcOP;
Point p0(0.2, 0.8);
Vector g = grad_funcOP(p0);
// use a lambda to transform the OP function to 1D
auto sliced_func = [&funcOP, &p0, &g] ( double t ) -> double {
// those variables ^^^ ^^^ ^^ are captured and used
return funcOP(p0 - t * g);
};
tabulate_function(sliced_func, 0, 0.5, 21);
Live example HERE.
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;
double x = 0,1;
doesn't compile (tries on on MSVC9.0). The error is
C2059 syntax error : 'constant'
I do realize that there's a comma there instead of a point, but shouldn't the line above be interpreted as the following?
double x = (0,1); //which is double x = 1;
Incidentally, the initialization compiles successfully with the parentheses.
I was thinking along the lines that operator , has a lower precedence than operator =, but in this case = is no operator, so this shouldn't be an issue. What syntactic rules determine that
double x = 0,1;
should be illegal?
Well, it's treated as
double x = 0; double 1;
that's why. Just like you'd write
double x = 0, y;
It's the syntax for a declaration, you're just attempting to declare 1 as a variable (which is wrong). Don't think there's much more to it...
During declarations, the comma in the absence of parenthesis is treated as a separator between declarations. For example:
double x = 0, y = 1;
or
double x = 0, y;
What you typed is the equivalent of
double x = 0;
double 1;
Which is obviously not correct.
Im trying to make a function that will return an element of type "point":
type point = {x : int, y : int};
fun pointadd (p1: point, p2: point) = (((#x p1) + (#x p2)), ((#y p1) + (#y p2)));
but SMLNJ doesn't seem to understand my intention that the result should be of type "point" as well:
use "test1.sml";
[opening test1.sml]
type point = {x:int, y:int}
val pointadd = fn : point * point -> int * int
point is a record type, but you are returning a tuple instead.
How about something like this:
fun pointadd (p1: point, p2: point) =
{ x = #x p1 + #x p2,
y = #y p1 + #y p2 };
You can add a type guard on the return type to make the type nicer, but it's equivalent:
fun pointadd (p1: point, p2: point) : point =
{ x = #x p1 + #x p2,
y = #y p1 + #y p2 };
It's been quite a while since my SML days but afair the type system does not resolve defined types automatically when printing the type signature. You could try something like this:
fun pointadd (p1: point, p2: point) = (((#x p1) + (#x p2)), ((#y p1) + (#y p2))): point