Casting of `arrayfire::Array` - casting

I'm using the arrayfire crate to open an image with af::load_image. This gives me a f32 array that I can do some processing on. After I am done, I would like to save it as an u8 image using af::save_image:
extern crate arrayfire as af;
fn main() {
let im = af::load_image("image".into(), false);
//let im2: af::Array = im.cast(); // Error: cannot infer type for T
//let im2: af::Array<DType::U8> = im.cast(); // Error: expected no type arguments
}
I can't figure out how to convert the array into a u8 type. I looked into the from method but I have no idea how to use it.

The signature for cast is cast<T: HasAfEnum>(&self) -> Array
Array type doesn't have type parameters. It is the cast method which has one. You need to provide type parameter to the cast method using turbofish syntax ::<_>
let im2 = im.cast::<u8>();

Related

casting a returned value from C++ function

I have following C++ code snippet
inline std::vector<std::unique_ptr<xir::Tensor>> cloneTensorBuffer(
const std::vector<const xir::Tensor*>& tensors)
{
auto ret = std::vector<std::unique_ptr<xir::Tensor>>{};
auto type = xir::DataType::XINT;
ret.reserve(tensors.size());
for (const auto& tensor : tensors) {
ret.push_back(std::unique_ptr<xir::Tensor>(xir::Tensor::create(
tensor->get_name(), tensor->get_shape(), xir::DataType{type, 8u})));
}
return ret;
}
I am not clear about the expression:
std::unique_ptr<xir::Tensor>(xir::Tensor::create(
tensor->get_name(), tensor->get_shape(), xir::DataType{type, 8u}))
Is the expression casting the value returned by xir::Tensor::create() to std::unique_ptr<xir::Tensor? I am confused since the C++ casting syntax is (type)expression
Can someone explain please.
regards,
-sunil puranik
This code takes a vector of raw pointers to Tensor objects, and returns a new vector of unique pointers to a new set of Tensor objects. Doesn't look like any explicit casting is taking place.
std::unique_ptr<xir::Tensor>( // create unique pointer to new Tensor object
xir::Tensor::create(
tensor->get_name(), // created with name and shape of the
tensor->get_shape(), // tensor pointed at in the original vector
xir::DataType{type, 8u} // and with unsigned 8-bit XINT datatype
)
)
Regarding casting - please don't consider e.g. (int)foo to be C++-style casting - that's legacy C-style casting. Amongst other things it's hard to find by searching a codebase!
C++ has:
static_cast
dynamic_cast
reinterpret_cast
const_cast
implicit conversion
There's more detail on this at cplusplus.com.

C++; How to write to an Vect3b pointer of opencv in a function

I have a small problem. I am having a function using a function with 2 Mat pointer objects given, but im having trouble writing to outImg channels to update the img.
void convolve5(Mat *inputImg, Mat *outImg, int *kernel5) {
int channelvaluepixel = inputImg->at<Vect3b>(x,y)[channel];
// loads of changes happening here
outImg->at<Vect3b>(x,y)[0] = channelvaluepixel;
}
Since outImg is a pointer i cannot point to its adress to change it, so i tried this to change the value within the pointer:
*outImg->at<Vect3b>(x,y)[0] = channelvaluepixel;
But this would not work either since the compiler gives me an:
Error: invalid type argument of unary '*' (have 'unsigned char')
Can somebody help?
You are dereferencing whole expression outImg->at<Vect3b>(x,y)[0] instead of just (*outImg).at<Vect3b>(x,y)[0] = channelvaluepixel;

How to make reference variable to boost::bimap.left?

I'm using boost::bimap to map integers to strings:
typedef boost::bimap<int, std::string> ParamIDStrings;
typedef ParamIDStrings::value_type id_pair;
extern const ParamIDStrings paramIDStrings;
I'm trying to create reference variables so I can write code like:
paramIDStringsByID.at(5);
// Instead of having to remember which side is which:
paramIDStrings.left.at(5);
But I'm having a hard time interpreting the Boost documentation, to understand of what type bimap::left is.
I tried:
// Compiler throws error: invalid use of template-name 'boost::bimaps::bimap' without an argument list
boost::bimaps::bimap::left &paramIDStringsByID = paramIDStrings.left;
// Compiler throws error: 'paramIDStrings' does not name a type
paramIDStrings::left_map &paramIDStringsByID = paramIDStrings.left;
// Compiler throws error: invalid initialization of reference of type boost::bimaps::bimap<int, std::__cxx11::basic_string<char> >::left_map
boost::bimaps::bimap<int,std::string>::left_map &cParamIDStringsByID = cParamIDStrings.left;
You can use auto & to let the compiler do the work for you.
If you want to know the type that gets deduced you can use one of the tricks from here to make the compiler tell you.
boost/bimap/bimap.hpp has a typedef for this: left_map and right_map. So you can do:
paramIDStrings::left_map &paramIDStringsByID = paramIDStrings.left;

Error: argument of type " float(*)[1] " is incompatible with parameter of type " float** "

I have a function with the following signature:
float* Interpolate(float t, UINT iOrder, UINT iDimension, float** ppPointsArray);
When trying to call it as follows:
float ppfValues[2][1];
ppfValues[0][0] = 0.0f;
ppfValues[1][0] = 10.0f;
float* pfResult = MyMathFuncs::Interpolate(0.5f,2,1,ppfValues);
I get the following error:
Error: argument of type float(*)[1] is incompatible with parameter of type "float**"
If I want to call it properly, I should do it like this:
float** ppfValues = new float*[2];
ppfValues[0] = new float(0.0f);
ppfValues[1] = new float(10.0f);
float* pfResult = MyMathFuncs::Interpolate(0.5f,2,1,ppfValues);
Now the question is: I thought float[x][y] was actually the same as a float**
Why are they not? What are the technical reasons? And what are they exactly, then?
I thought float[x][y] was actually the same as a float**
It all boils down to the fact that arrays and pointers aren't equivalent. Below is a list of C FAQs (even if this is a C++ question) which stress this fact in various ways.
My compiler complained when I passed a two-dimensional array to a
function expecting a pointer to a pointer.
But I heard that char a[] was identical to char *a
So what is meant by the ``equivalence of pointers and arrays'' in C?
How do I write functions which accept two-dimensional arrays when the width is not known at compile time?

How to use a Judy array

I am interested in Judy Arrays and try to use it. But i had unable to do any useful thing using it. Every time it gives me casting errors.. Sample c++ code and the error given below.
#include "Judy.h"
#include <iostream>
using namespace std;
int main()
{
int Rc_int; // return code - integer
Word_t Rc_word; // return code - unsigned word
Word_t Index = 12, Index1 = 34, Index2 = 55, Nth;
Word_t PValue; // pointer to return value
//Pvoid_t PJLArray = NULL; // initialize JudyL array
Pvoid_t JudyArray = NULL;
char String[100];
PWord_t _PValue;
JSLI( JudyArray, _PValue, (uint8_t *) String);
return(0);
} // main()
This gives me the error
m.cpp: In function ‘int main()’:
m.cpp:19: error: invalid conversion from ‘long unsigned int**’ to ‘void**’
m.cpp:19: error: initializing argument 1 of ‘void** JudySLIns(void**, const uint8_t*, J_UDY_ERROR_STRUCT*)’
Please anyone help me to figure out what is the error what i'm doing..
Thanks
According to the documentation, you have the _PValue and JudyArray parameters reversed. Make your call look like this:
JSLI( _PValue, JudyArray, (uint8_t *) String);
Also, try not compiling it as C++ code. So far, your test uses no C++ features. I bet it will compile as C code. It looks like JudyArray relies on the fact that C will do certain kinds of implicit conversions between void * and other pointer types.
If this is the case, I'm not sure what to do about it. The error messages you're getting tell me that JSLI is a macro. In order to fix the error message you have in the comments on this answer, you'd have to reach inside the macro and add a typecast.
These kinds of implicit conversions are allowed in C because otherwise using malloc would always require ugly casts. C++ purposely disallows them because the semantics of new make the requirement that the result of malloc be cast to the correct type unimportant.
I don't think this library can be used effectively in C++ for this reason.
It seems that, you pass JudySLIns(void**, const uint8_t*, J_UDY_ERROR_STRUCT*) a wrong parameter, the first one, you'b better check it!
For integer keys there is a C++ wrapper at http://judyhash.sourceforge.net/