Hello, I have some function that inside I am trying to take the absolute value of an array using std::valarray. But I keep getting the errors:
1 2
no instance of overloaded function "abs" matches the argument lis --argument types are: (double *)
no suitable conversion function from "stad::valarray<double>" to "double*" exists
My array U is defined as the following:
double U[3] = {-10,0,0};
The error showing in the function:
1 2 3 4 5 6 7 8 9 10 11 12
std::valarray<double> U;
std::valarray<double> bar = abs(U); // here
double vMaxArr[7];
// some calculations
vMaxArr[6] = Arr1DMax(bar, 3); // here
double max = Arr1DMax(vMaxArr, 7);
// some calculations
}
Basically, I am asking how to take the absolute value of array U and use it as an input in Arr1DMax which is:
1 2 3 4 5 6 7 8
double Arr1DMax(double arr[], int arrLength){
double max = 0.0;
for (int i = 0; i < arrLength; i++){
if (arr[i] > max){
max = arr[i];
}
}
return max;
valarray can do some slick stuff, but so far what I see for this task is all syntax sugar to hide a loop that takes abs of all the elements and does whatever with the results. There is nothing wrong with that, but its not necessary either -- you are copying U for no real reason, allocating memory for no real reason (valarray does it for you, hidden), and so on. Pick a container and use it, and if you have to do an occasional loop yourself (or use transform to hide it) so be it (if you choose a C array type thing) or go ahead and use valarray from the the onset (probably the better way).
Okay, so I then completely misunderstood the idea behind std::valarray, I thought it was an array. So, this is just a function in the main code I do define U array there and I am trying to use it as a variable that I can change for different results. All I wanted to do is just take the absolute value, and I saw that abs(x) is not used for arrays so I went with std::valarray.
I am getting confused really on how to find an absolute value of an array, do I just simply do a for loop?
the fancy way: (here, if U is a container, the begin and end, if it is an array, you can use pointers)
std::transform(U.begin(), U.end(),U.begin(), ::abs);
this is almost exactly the same as the for loop, when it compiles, the for loop may have an extra register in use or something minor.
your loop looks correct, assuming U is actually signed type, but its way overkill. A condition costs you as much effort as the work you bypassed here, so that is just code bloat. Given that your code looks correct in that loop, you may have a bug elsewhere that messes up the sign.
valarray, vector, std::array, and C arrays (int x[10] type) are all 'arrays' sort of. Or another way to say it, the first 3 are objects that wrap the 'concept' of an array like container into an object oriented tool with many extra features. you can use ANY of them for this, and the choice depends on what you want to do. Valarray is really good at certain types of number crunching, vectors are more generic data dump containers that just hold the data in cells, std:array is just enough object to remove the aggravations of C arrays, and C arrays are just memory locations, really.