Load set of images - Matlab-->C++ translation - c++

I have a Matlab script that I'm trying to convert to C++ (see below) because it is extremely slow. I'm a C++ newbie and to start I tried using codegen but it doesn't work (I got the message ??? This text contains non-empty top-level expressions. It appears to be a script.)
Do you have any suggestion on how to start to convert the code? Also, what is the best C++ function to do the job of fitsread?
Here is my code:
clear;
number_projections = 10;
imgs_per_proj = 2000; % Number of images per projection
% Lets load the reference images relative to the various wavelengths
R1 = zeros(imgs_per_proj, 512, 512);
R2 = zeros(imgs_per_proj, 512, 512);
l = 0;
for k = 1:imgs_per_proj
s = sprintf('Ref/R1_000_%05i.fits',k-1);
t = sprintf('Ref/R2_000_%05i.fits',k-1);
l = l + 1;
R1(l,:,:) = fitsread(s);
R2(l,:,:) = fitsread(t);
end

codegen requires that the MATLAB code you're trying to convert be in a function and it seems you are trying to convert a script
However, even if you do that, fitsread does not appear to be a supported function within codegen. Here's a list of supported functions:
http://www.mathworks.com/help/simulink/ug/functions-supported-for-code-generation--alphabetical-list.html
There's no "built-in" function within C++ that's going to replace fitsread - for that you need a library. There's a C++ FITS library called CCFits that you can find here: http://heasarc.gsfc.nasa.gov/fitsio/CCfits/
They should have tutorials that you could follow.

Related

Translating wrapped function like struct of C/C++.bt (Binary Template) to Java 8

Sorry, I have almost 20 years without touching C/C++.
I Would like translate this code to Java 8, I found this Reference Manual.
I was reading that in this link.
You can read...
Binary Templates are easy to write and look similar to C/C++ structs except they may contain if, for, or while statements as well as functions or complex expressions.
Powerful enough to parse almost any binary file format.
Can be set to run automatically when files are opened.
Templates may be shared and a list of templates for download is available in our Template Repository.
I begins and in the line 2063 I found (sorry, I could only translate, sad 4 lines :(! ).
APFS apfs(0);
I was reading C - function inside struct but looks, so many different!
Reviewing I jump to the line 1994, it looks like a structure with a function call, instead of having attributes!!!.
typedef struct APFS(uint64 apfs_offset) {
DefineApfsContainer(apfs_offset);
} ;
Inmediatly you can see in the line 1998
void DefineApfsContainer(uint64 apfs_offset) {
Apfs_Offset = apfs_offset;
FSeek(Apfs_Offset);
if (!CheckApfsAndSetBlockSize()) {
Printf("\nError, starting point not an APFS container superblock. Set the 'Apfs_Offset' variable to correct value!");
Exit(1);
}
obj csb;//container super block in block zero
SeekBlock(csb.body.xp_desc_base);
CheckpointDesc cp(csb.body.xp_desc_blocks);
//SeekBlock(csb.body.xp_data_base);
//obj checkpoint_data_nx[csb.body.xp_data_blocks] <optimize=false>;
// Checkpoint processing
local uint i = 0;
local uint64 max_xid = 0;
local uint64 max_xid_block_pos = 0;
SeekBlock(csb.body.xp_desc_base);
local uint64 base_pos = FTell();
local uint64 pos = 0;
for (i=0; i< csb.body.xp_desc_blocks; ++i) { // assuming cont. blocks
if (cp.checkpoint_desc_nx[i].hdr.type == obj_type_container_superblock) {
if (cp.checkpoint_desc_nx[i].hdr.xid >= max_xid) {
// validate it
pos = base_pos + (i * Block_Size);
if (fletcher64(pos, Block_Size) == 0) {
max_xid = cp.checkpoint_desc_nx[i].hdr.xid;
max_xid_block_pos = pos;
}
}
}
}
if (max_xid > csb.hdr.xid)
Printf("\nFound newer xid=%Lu # offset 0x%Lu. Using this Container superblock.", max_xid, pos);
FSeek(pos);
obj valid_csb;
BookmarkVolumes(valid_csb);
if (valid_csb.body.efi_jumpstart) {
SeekBlock(valid_csb.body.efi_jumpstart);
obj efi_info;
}
/*if (valid_csb.body.keylocker_block_count) {
SeekBlock(valid_csb.body.keylocker_paddr);
obj keybag; // This is encrypted!
}*/
}
I need to understand what does that (I don't mean the code, but the way of coding), in order to translate.
How should I understand this code (a function as a structure or a structure from a function)?
The nugget of subject.
How should I translate it to Java?
This code doesn’t quite translate to Java because it’s code-generating code, ie. code that some tool uses to generate the actual C-like code (in a nutshell), or code for a bespoke virtual machine that then implements the data extraction and data packing. The idiomatic way to do this in Java without writing a stand-alone tool would be by attributes and similar mechanisms, introspection, and runtime code generation, repurposing Java syntax to express the same idea. You could attempt to do manual translation - that would grow the code a whole lot. The binary template concept is very powerful - leads to very concise code that would otherwise be tedious to implement.
I’d say that a manual translation will be more work than writing the translator, because you’ll be debugging all the manual mistakes till the cows come home. The syntax is limited enough so that a parser and translator written in Java will be about the same number of lines as a “straightforward” Java implementation of the binary template.
You may look at the tool this template is written for and see if the tool offers a way of translating the template. If the tool is open source then you already have a parser :)

Declaring variables in Python 2.7x to avoid issues later

I am new to Python, coming from MATLAB, and long ago from C. I have written a script in MATLAB which simulates sediment transport in rivers as a Markov Process. The code randomly places circles of a random diameter within a rectangular area of a specified dimension. The circles are non-uniform is size, drawn randomly from a specified range of sizes. I do not know how many times I will step through the circle placement operation so I use a while loop to complete the process. In an attempt to be more community oriented, I am translating the MATLAB script to Python. I used the online tool OMPC to get started, and have been working through it manually from the auto-translated version (was not that helpful, which is not surprising). To debug the code as I go, I use the
MATLAB generated results to generally compare and contrast against results in Python. It seems clear to me that I have declared variables in a way that introduces problems as calculations proceed in the script. Here are two examples of consistent problems between different instances of code execution. First, the code generated what I think are arrays within arrays because the script is returning results which look like:
array([[ True]
[False]], dtype=bool)
This result was generated for the following code snippet at the overlap_logix operation:
CenterCoord_Array = np.asarray(CenterCoordinates)
Diameter_Array = np.asarray(Diameter)
dist_check = ((CenterCoord_Array[:,0] - x_Center) ** 2 + (CenterCoord_Array[:,1] - y_Center) ** 2) ** 0.5
radius_check = (Diameter_Array / 2) + radius
radius_check_update = np.reshape(radius_check,(len(radius_check),1))
radius_overlap = (radius_check_update >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap), dtype=int)
overlap_update = np.reshape(overlap,(len(overlap),1))
overlap_logix = (radius_overlap == 1)
idx_true = overlap_update[overlap_logix]
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
A similar result for the same run was produced for variables:
radius_check_update
radius_overlap
overlap_update
Here is the same code snippet for the working MATLAB version (as requested):
distcheck = ((Circles.CenterCoordinates(1,:)-x_Center).^2 + (Circles.CenterCoordinates(2,:)-y_Center).^2).^0.5;
radius_check = (Circles.Diameter ./ 2) + radius;
radius_overlap = (radius_check >= distcheck);
% Now actually check the overalp condition.
if sum(radius_overlap) == 0
% The new circle does not overlap so proceed.
newCircle_Found = 1;
debug_value = 2;
elseif sum(radius_overlap) == 1
% The new circle overlaps with one other circle
temp = 1:size(radius_overlap,2);
idx_true = temp(radius_overlap == 1);
radius = distcheck(1,idx_true) - (Circles.Diameter(1,idx_true)/2);
In the Python version I have created arrays from lists to more easily operate on the contents (the first two lines of the code snippet). The array within array result and creating arrays to access data suggests to me that I have incorrectly declared variable types, but I am not sure. Furthermore, some variables have a size, for example, (2L,) (the numerical dimension will change as circles are placed) where there is no second dimension. This produces obvious problems when I try to use the array in an operation with another array with a size (2L,1L). Because of these problems I started reshaping arrays, and then I stopped because I decided these were hacks because I had declared one, or more than one variable incorrectly. Second, for the same run I encountered the following error:
TypeError: 'numpy.ndarray' object is not callable
for the operation:
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
which occurs at the bottom of the above code snippet. I have posted the entire script at the following link because it is probably more useful to execute the script for oneself:
https://github.com/smchartrand/MarkovProcess_Bedload
I have set-up the code to run with some initial parameter values so decisions do not need to be made; these parameter values produce the expected results in the MATLAB-based script, which look something like this when plotted:
So, I seem to specifically be having issues with operations on lines 151-165, depending on the test value np.sum([radius_overlap]) and I think it is because I incorrectly declared variable types, but I am really not sure. I can say with confidence that the Python version and the MATLAB version are consistent in output through the first step of the while loop, and code line 127 which is entering the second step of the while loop. Below this point in the code the above documented issues eventually cause the script to crash. Sometimes the script executes to 15% complete, and sometimes it does not make it to 5% - this is due to the random nature of circle placement. I am preparing the code in the Spyder (Python 2.7) IDE and will share the working code publicly as a part of my research. I would greatly appreciate any help that can be offered to identify my mistakes and misapplications of python coding practice.
I believe I have answered my own question, and maybe it will be of use for someone down the road. The main sources of instruction for me can be found at the following three web pages:
Stackoverflow Question 176011
SciPy FAQ
SciPy NumPy for Matlab users
The third web page was very helpful for me coming from MATLAB. Here is the modified and working python code snippet which relates to the original snippet provided above:
dist_check = ((CenterCoordinates[0,:] - x_Center) ** 2 + (CenterCoordinates[1,:] - y_Center) ** 2) ** 0.5
radius_check = (Diameter / 2) + radius
radius_overlap = (radius_check >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap[0]), dtype=int).reshape(1, len(radius_overlap[0]))
overlap_logix = (radius_overlap == 1)
idx_true = overlap[overlap_logix]
radius = dist_check[idx_true] - (Diameter[0,idx_true] / 2)
In the end it was clear to me that it was more straightforward for this example to use numpy arrays vs. lists to store results for each iteration of filling the rectangular area. For the corrected code snippet this means I initialized the variables:
CenterCoordinates, and
Diameter
as numpy arrays whereas I initialized them as lists in the posted question. This made a few mathematical operations more straightforward. I was also incorrectly indexing into variables with parentheses () as opposed to the correct method using brackets []. Here is an example of a correction I made which helped the code execute as envisioned:
Incorrect: radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
Correct: radius = dist_check[idx_true] - (Diameter[0,idx_true] / 2)
This example also shows that I had issues with array dimensions which I corrected variable by variable. I am still not sure if my working code is the most pythonic or most efficient way to fill a rectangular area in a random fashion, but I have tested it about 100 times with success. The revised and working code can be downloaded here:
Working Python Script to Randomly Fill Rectangular Area with Circles
Here is an image of a final results for a successful run of the working code:
The main lessons for me were (1) numpy arrays are more efficient for repetitive numerical calculations, and (2) dimensionality of arrays which I created were not always what I expected them to be and care must be practiced when establishing arrays. Thanks to those who looked at my question and asked for clarification.

PID controller and transfer function in C++

I have a PID controller working in simulink, but I want to pass it to C++ code. I found how to make a PID with code, something like this:
error = input - refeed;
iError += error * sampleTime;
dError = (error - lastError)/ sampleTime;
//PID Function
output = Kp * error + Ki * iError + Kd * dError;
refeed = output;
lastError = error;
But, that's the only clear thing I got in my research.
I need to know what's the next step, I have the transfer function discretized but I'm not sure about what should I do with the "z" parameters, the times, ...
Is it possible to pass manually a PID controller to C++? How?
The Temperature Control Lab passes a PID output from Python to an Arduino that runs C++ code through a serial USB interface. It is easier to plot values with Python than C++ if you can create an interface for your application. GitHub source code is here.
For the digital control systems, you need to sample the data and execute the controller at every sampling time. z-transform converts the continuous system to the discrete system.
For exampl, if your sampling time is '1', you can express a simple time-series model as below,
y(t) = a1*u(t-1) + a2*u(t-2)
--> y(t) = a1*z^-1*u(t) + a2*z^-2*u(t)
--> y(t) = A(z)u(t), where A(z) = a1*z^-1 + a2*z^-2
a1, a2 = FIR coefficients
However, this time-shift operator 'z^-1' does not appear in your code. It is implicitly expressed with your sampling-time and FOR or DO loop depending on the language that you are using.
Please see the python code for velocity form of PID controller. Velocity form is a little bit easier to implement because you don't worry about the additional logic for the anti-reset windup.
for i in range(1, ns): #ns = simulation time
# PID Velocity form
e[i] = sp[i] - pv[i]
P[i] = Kc * (e[i] - e[i-1])
I[i] = Kc*delta_t/tauI * (e[i])
D[i] = Kc*tauD/delta_t * (pv[i] - 2*(pv[i-1]) + pv[i-2])
op[i] = op[i-1] + P[i] + I[i] + D[i]
if op[i] < oplo or op[i] > ophi:
# clip output
op[i] = max(oplo,min(ophi,op[i]))
You can also find an example of a PID controller using a GEKKO package in the following link.
https://apmonitor.com/wiki/index.php/Main/GekkoPythonOptimization
Yes it is possible. Have you considered using someone else's code? Or do you want to write it yourself? If you have no problem using allready written code, check out Github. It has a lot of PID projects. For example PID-controller. It has a usage example and you only have to pass in your p, i and d parameters (which you allready got from Matlab).
Good luck!
Basically, you should send the values somewhere. Reading through the comments, you want to make a plot of the output variable in time, so I guess your best bet (and easier way) is to use gnuplot.
Basically, output the data in a text file, then use gnuplot to display it.

Passing a string variable between my c++ code to matlab

I am new to matlab, and coding is not my job, I just use it for some side projects. So I don't really know what I am talking about, and I hope you'll understand that :)
So I installed matlab on my computer and would like to use its libraries to plot some very simple graphs during the execution of my code (histograms, scatter plots, whatever). Plotting those graphs is not the first purpose of my code, I just find that easier to plot them during the execution rather than exporting them as a CSV file, and then plotting manually through excel.
Question: I managed to make visual C++ "communicate" with matlab. I am passing some data using arrays, but I'd also like to pass a string (a path such as "C:\test\") as I'd like to automatically save those graphs once generated into a precise directory. I haven't found any way of doing it so far.
Here is a bit of my c++ code, which is really simple:
Engine *ep;
ep = engOpen(NULL);
double *ArrayOne;
double *ArrayTwo;
const int Asize = Area.size();
ArrayOne = new double[Asize];
ArrayTwo = new double[Asize];
for (int i = 0; i <= Area.size() - 1; i++) {
ArrayOne[i] = Area[i][1];
ArrayTwo[i] = Area[i][2]
}
mxArray* ONE = mxCreateDoubleMatrix(Asize, 1, mxREAL);
memcpy((void*)mxGetPr(ONE), (void*)ArrayOne, sizeof(double)*Asize);
engPutVariable(ep, "one", ONE);
mxArray* TWO = mxCreateDoubleMatrix(Asize, 1, mxREAL);
memcpy((void*)mxGetPr(TWO), (void*)ArrayTwo, sizeof(double)*Asize);
engPutVariable(ep, "two", TWO);
engEvalString(ep, "plottest");
delete[]ArrayOne;
delete[]ArrayTwo;
engClose(ep);
And the file Plottest.m:
h1= histogram(one);
h1.EdgeColor = 'black';
h1.FaceColor = 'white';
hold on;
h2 = histogram(two);
h2.EdgeColor = 'blue';
h2.FaceColor = [0.5 0.5 0.5];
alpha(h1,.5);
alpha(h2,.8);
saveas(gcf,'C:\PhD\SVG2GMSH\SVG\test.png');
How can I replace my hard coded path into my m file ("C:\PhD\SVG2GMSH\SVG\test.png") by a more elegant variable that would contain it ?
Thank you for your help. Also, let me know if you have any other suggestions in order to make my code look/work better :)
Flo
I don't see what benefit a variable would bring when you'd only need to update the value of the variable anyway.
Your best bet is to use a relative path: saveas(gcf, 'test.png') then the file is taken from the current working directory. The documentation doesn't actually outright state this, but it's basically how computers work, so… give it a go!

matlab script to c++

I am trying to implement this person's code: http://iris.lib.neu.edu/civil_eng_theses/30/ but I can not generate a working executable in visual studio because I am missing 2 files: myoutput.cpp and PrintTimeReferencedVariable.cpp. I am unclear if the Matlab builder is supposed to generate them or I write them.
The myoutput.cpp is supposed to be a C++ file that does essentially a dlmwrite. It is used as follows:
function [] = Output_01(FileName, FileNameLenght, OutputData, OutputSize1, OutputSize2)
coder.inline('never')
coder.ceval( 'myoutput', FileName, FileNameLenght, OutputData, OutputSize1, OutputSize2);
end
% %% Matlab Version: to run the model in Matlab uncomment below, comment above
% function [] = Output_01(FileName, FileNameLenght, OutputData, OutputSize1, OutputSize2)
% dlmwrite(FileName, OutputData,'-append','coffset',0,'delimiter','\t','precision','%6.6G')
% precision = 4;
% disp( num2str( OutputData,precision))
% end
Where the commented out is the matlab version of the file and the top is what is built into C++. The files are supposed to write to the directory: C:\matlab-results-from-cpp.
The PrintTimeReferencedVariable.cpp looks like a date function that should do:
% Date = datestr(now, 'yyyy-mm-dd-HH-MM-SS' );
%% Matlab Version: to run the model in Matlab uncomment above, comment below
Date = '2012-09-16-09-19-20';
coder.ceval('PrintTimeReferencedVariable', coder.wref(Date));
Any insight into this would be much help. I'm still waiting to hear back from the author but it would still be helpful to hear all of your input as this is my first time in C++ and building projects in Matlab.
Thanks!
Seems like the text is pretty clear on what you do, though I can understand the confusion not coming from a C++ background:
5)
“Project Settings ”adjustments: Open ‘More settings’,then in ‘All Settings’ tab, choose for ‘Language’ C ++; In “Speed” tab mark only “Saturate on integer overflow”, unmark everything else; in “Custom Code ” tab, copy and paste the first lines the functions “myoutput.cpp” and “PrintTimeReferencedVariable.cpp”, followed by semicolon or see below the text:
void PrintTimeReferencedVariable (char * DateOut);
void myoutput(const char* _filename, int fileNameLen, double* data, int n, int m);
So you create the files "myoutput.cpp" and "PrintTimeReferencedVariable.cpp". Copy and paste the code into the respective cpp files. Then add the prototype(the second quote) to your header or at the top of those files.