passing a 2d matrix from java to C++ file through jni - java-native-interface

I have a 2d matrix in java say in a file MyClass.java in the method java_method() and I have declared a native method say c_method(). the matrix is float type like:
float[][] pos_matrix;
of size 3by4 and I have initialized the matrix in java. Now I want to pass this matrix to my cpp file in the jni. How to do that?

Two options:
encode the matrix in 1D array of length 12, pass as float[]. Results in jfloatArray on native side. Cannot be used directly, read about Get/ReleaseFloatArrayElements
wrap the Java matrix in a facade class with method float GetValueAt(int,int) (or similar) and access on native side by passing the instance (results in jobject on native side) and then calling that method (GetMethodID/CallFloatMethod)
Option 1 is simpler (less coding), option 2 is cleaner in "OO way" - separation of concerns. With option 1 you can practically modify the array when JVM is not looking.

Related

Convert a vector<dlib::point> to an NSArray so it can be passed to a Swift class

I'm using dlib's facial landmark detector and want to store the facial landmark coordinates in an array that can be used in Swift.
At the minute I've stored the landmark coordinates in a vector:
std::vector<dlib::point> facialLandmarks;
for (unsigned long k = 0; k < shape.num_parts(); k++) {
dlib::point p = shape.part(k);
facialLandmarks.push_back(p);
}
I now want to write a function that will convert the vector into an NSArray so that I can return the array and use it within my Swift code.
When I try things like the following:
NSArray* facialLandmarksArray = &facialLandmarks[0];
I get an error:
Cannot initialize a variable of type 'NSArray *__strong' with an rvalue of type 'std::__1::__vector_base<dlib::vector<long, 2>, std::__1::allocator<dlib::vector<long, 2> > >::value_type *' (aka 'dlib::vector<long, 2> *')
I really know very little about Objective-C or C++ but need to use it for Dlib. Any help would be really appreciated!
NSArrays can only contain Objective-C objects, no C++ objects. So you have to convert your points to NSValues first. Something like this should work:
NSMutableArray* facialLandmarksArray = [NSMutableArray arrayWithCapacity: facialLandmarks.size()];
for (auto const& pt: facialLandmarks) {
[facialLandmarksArray addObject: [NSValue valueWithCGPoint:CGPointMake(pt.x, pt.y)]];
}
And make sure this is compiled as Objective-C++ (file ending *.mm).
However, note that this does not scale well for large vectors. Swift and C++ are both able to make sure that the values of such arrays/vectors are stored in consecutive memory, bridging through Objective-C destroys this locality.
A couple of the challenges here are:
1) We want to minimize copying of the landmark points, since such copying will affect software performance and memory footprint.
2) How do we use C++ vector's members, instances of type dlib::point in this case, in Swift code?
Addressing these challenges depends on the use case. Some questions to consider:
1) How important is performance/memory footprint? If this is not an issue, copying the values when making them available to Swift is OK. Of course, this also depends on whether C++ code has to use values changed by Swift.
2) How many landmark points are we talking about? If it's a hundred points or so, then copying them is unlikely to be a performance hit.
3) Is Swift code just going to use the values of the landmark points returned by the C++ library, or is it going to modify those values and expect C++ code to "see" those changes?
4) How many times, typically, will Swift code access each of the landmark points? If each point is accessed multiple times, then it's better to copy all the points once into a structure that can be used in Swift without creating a copy on each access rather than making a copy of a coordinate each time Swift accesses it.
5) How much complexity can be tolerated? Are you willing to write a lot of C++ code? Are you comfortable working with pointer types in Swift, e.g. UnsafeMutablePointer?
And here are some ideas on how to do this:
1) Construct, in Objective-C++, a collection that can be used in Swift and copy landmark point coordinate values into that structure. #Tobi's answer is an example.
2) Similar to (1) above, but the Swift-accessible collection contains pointers to coordinate values.
3) Write an Objective-C++ class whose interface is accessible from Swift and all C++-specific code is hidded in the implementation. The interface could allow Swift code to read (and write, if needed), specific coordinates of specific landmark points.
4) A variation of (3) where Swift code accesses pointers to the coordinate values. Care would be needed when using these on the Swift side to avoid copying of the coordinate values.
If you provide some specifics about your use case, I can try to come up with an example.

Memory sharing between Matlab and C++ in MEX

I'm currently trying to write a program that processes a fairly large file (~16GB) and then performs analysis upon it. Ideally, I would do the data processing in C/C++ (I already have an efficient implementation written) and then do the analysis in Matlab to make use of its efficient algorithms and ease of use.
My natural inclination is to use MEX to call routines written in C at the beginning of the program and then continue in Matlab. What I want to know (and what I for whatever reason can't seem to find online) is the way in which memory would be shared if I were to use this method:
Say that I were to make a single large heap-allocated array in C to pass to Matlab. Would this array need to be copied in memory before my Matlab functions could work on it, or would Matlab be able to access the original array directly, with no extra copying? I assume and hope that this will work in the second way, but I would rather make sure before spending my time and effort.
Memory can indeed be shared if you used the functions provided by Matlab for this purpose. For example, to create a matrix that is passed back to matlab you can use something like this:
plhs[0] = mxCreateNumericArray(2, out_dims, mxDOUBLE_CLASS, mxREAL);
double *result = mxGetPr(plhs[0]);
That would create an array in place, that matlab will later use. You fill it in using *result, and since the memory was allocated by use of the mx functions, then matlab will delete it when appropriate.

Using Simulink Coder - atomic change of multidimensional parameters (matrix, vector)

I am using Simulink and Simulink Coder to generate a dll of arbitrary Models. My C Application uses the mathworks CAPI.
It runs arbitrary models (hard real time below 1 ms) and is able to modify any parameters of the model (by using the tunable parameters).
For simlpe scalar values I am obtaining the adress of the value.
Pseudocode:
void* simplegain = rtwCAPI_GetSignalAddrIdx()
*simplegain=42;
Everything runs fine. However, this approach can not be applied if I want an atomic change of complete vector and matrix.
For multidimensional Data I used memcopy to write all values from a destination to the result of GetSignalAddIdx(). Measurements have shown that using memcopy is to slow.
Analysing the generated Code show various calls of rt_Lookup
real_T rt_Lookup(const real_T *x, int_T xlen, real_T u, const real_T *y)
// x is the pointer the matrix The Adress of the matrix is declared in a global structure `rtDataAddrMap` statically. I can read it out, but do not know how to change.
What I like to achieve is:
Define a second map in my application (same size).
Write all new value the this second map.
Change just the pointer in rtDataAddrMap to activate the second
map.
The general question:
How can I achieve to change multidimensional parameters atomically?
What is the regular way to do this? (Code Generation Options etc..)
The specific question: (if my approach was right)
What are reasonable solutions to change the data pointer of a matrix?
Atomic in the sense of calling an instruction which does its work in a single clock cycle (and thus not possible to interrupt) is not possible to achieve when it comes to this kind of multidimensional arrays. Instead you will need some kind of real time mechanism like a mutex or semaphore to protect your data. Mutexes and semaphores are built upon atomic operations which guarantees that two processes will not be able to consume the same resource at once.
Your approach with ping pong buffering of your data area will probably improve performance. Unfortunately I do not have enough experience from Mathworks generated code to tell how to implement that.

Passing byte array to lua script method from C++

How can i pass a byte array as an argument to lua script method from C++ code?
Are only int, float or string data types allowed?
Also how can i retrive byte array from lua script method?
I will pass a raw byte array to script. It will parse and use it.
Thanx.
Depends what you want to do. Lua strings are immutable byte arrays, so if they're small you're probably best off simply turning the byte array into a string with lua_pushlstring and passing it in like that --- yes, embedded \0 is supported and works fine. But because they're immutable Lua will end up copying the string every time you want to modify it, so it may not be suitable for your requirements.
Other options are:
copy the data back and forth between your C++ byte array and a Lua array (that is, table of numbers). This will be fairly expensive in memory, but is probably the easiest way.
wrap you C++ byte array in a lightuserdata and provide Lua bindings to let you access it directly. This is the most efficient, but is quite a lot of code.
Int and float values will be converted to Lua's number type (by default, double).
If the script itself just needs to keep a pointer to pass between functions, blobs of C data are usually pushed as light userdata:
lua_pushlightuserdata(L, bufptr);
When passing arrays of bytes to Lua, strings are normally used (strings of arbitrary data can be created using lua_pushlstring):
lua_pushlstring (L, bufptr, buflen);
This will create an immutable string in Lua, which can only be modified by creating new strings.
If you need to work with mutable byte buffers in Lua (not recommended- low-level byte manipulation is what C was designed for and Lua was not), the best bet is to create a userdata type for the buffer with methods to get and set tailored to the use case (individual positions as numbers, ranges as strings or tables of numbers).

C++ 2D growing array like MATLAB

I have read some posts about dynamic growing arrays in C, but I can't see how to create a 2D growing array (like in MATLAB).
I have a function to construct an array for some image processing, but I don't know what will be the size of this array (cols and rows). How can I create this?
I read something about malloc and realloc. These functions are portable or useful for this problem.
EDIT: SOLVED, using the Armadillo library, a C++ linear algebra library.
Simplest is with pointers
int nrows = 10;
int ncols = 5;
double* matrix = new double[mrows*ncols];
And then you can access it as if it's a 2D array like.
So if you want matrix[row][col], you'd do
int offset = row*ncols+col;
double value = matrix[offset];
Also, if you want the comfort of Matlab like matrixes in C++, look into Armadillo
If you're doing image processing, you might want to use the matrix and array types from opencv.
By growing an array like Matlab, I'm assuming you mean doing things like:
mat = [mat; col]
You can resize a matrix in C++, but not with a clean syntax like the one above.
For example, you can use std::vector<std::vector<T>> to represent your matrix.
std::vector<std::vector<int> > mat;
Then to add a column:
for (int i=0; i<mat.size(); i++) mat[i].push_back(col[i]);
or to add a row
mat.push_back(row); // row is a std::vector<int>
+1 for OpenCV, especially useful if you are doing image analysis, as it abstracts the underlying data type (GRAYSCALE, RGB, etc.).
C++ doesn't have a standard matrix class per-se. I think there were too many different uses of such a class that made a one-size-fit all solution impossible. There is an example and discussion in Stroustrup's book (The C++ Programming Language (Third Edition)) as to a simple implementation for a numerical matrix.
However, for image processing it's much better to use an existing library.
You might have a look at CImg. I've used it before and found it quick and well documented.
If you are on an AMD machine I know there is an optimised library for image processing from AMD, the Framewave project Framewave Project.
Also, if you are used to MATLAB style code then you may want to look at it++.
I think the project aim is for it to be as similar to MATLAB as possible.