I have difficulties while converting the following matlab line into C++:
for i=1:height
for j=1:width
if (match == 0)
[min_w, min_w_index] = min(w(i,j,:));
mean(i,j,min_w_index) = double(data(i,j));
sd(i,j,min_w_index) = sd_init;
end
rank = w(i,j,:)./sd(i,j,:);
rank_ind = [1:1:C];
end
end
Especially I don't know how to covert the "min_w_index" part. Could someone help me on this point?
Most common solution for min function in such case is
int min_w = w[i][j][0];
int min_w_index = 0;
for (k = 1; k < maxk; k++)
if (w[i][j][k] < min_w)
{
min_w = w[i][j][k];
min_w_index = k;
}
Don't forget that C++ has zero-based index, but Matlab one-based. I already see problem in your comment.
Related
I was trying to code for following program
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals [1,3],[6,9] insert and merge [2,5] would result in [1,5],[6,9].
Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] would result in [1,2],[3,10],[12,16].
This is the relevant part of my program
here. I want to erase the few positions from the vector
then I am getting the following error
error: stray '\177' in program
intervals.erase(intervals.begin()+(p+1),intervals.begin()+(q+1));
vector<Interval> Solution::insert(vector<Interval> &intervals, Interval newInterval) {
int n = intervals.size();
int p=-1,q=-1,a,b;
for(int i=0;i<n;++i){
if(intervals[i].start <= newInterval.start <= intervals[i+1].end)
p = i;
else if(intervals[i].end < newInterval.start < intervals[i+1].start)
a = i;
if(intervals[i].start <= newInterval.end <= intervals[i+1].end)
q = i;
else if(intervals[i].end < newInterval.end < intervals[i+1].start)
b = i;
}
int x,z;
if(p != -1 && q != -1)
x = q-p;
if(x > 0){
z=intervals[q].end;
intervals.erase(intervals.begin()+(p+1),intervals.begin()+(q+1));
intervals[p].end = z;
}
return vector
}
Did you copy that code from a website?
I managed to reproduce your result with this snippet:
const char* msg = "You can't copy this";
When copied and put on coliru here you'll get the same error code.
What I used for the above snippet in HTML code was:
<code>const char* msg = </code><code>"You can't copy this";
</code>
Note the character I put in there.
To fix that, you can use a decent editor like Notepad++ that will make the stray characters visible:
I'm trying to work out what the equivalent a[++j]=*pr++; in the following code (which comes from a MatLab mex file) is in Python. I've found out that 'pr' is a pointer to the first element of the input array, but I can't get my head around what is happening to j. Can someone explain what is happening there in simple terms without pointers etc?
rf3(mxArray *array_ext, mxArray *hs[]) {
double *pr, *po, a[16384], ampl, mean;
int tot_num, index, j, cNr;
mxArray *array_out;
tot_num = mxGetM(array_ext) * mxGetN(array_ext);
pr = (double *)mxGetPr(array_ext);
array_out = mxCreateDoubleMatrix(3, tot_num-1, mxREAL);
po = (double *)mxGetPr(array_out);
j = -1;
cNr = 1;
for (index=0; index<tot_num; index++) {
a[++j]=*pr++;
while ( (j >= 2) && (fabs(a[j-1]-a[j-2]) <= fabs(a[j]-a[j-1])) ) {
ampl=fabs( (a[j-1]-a[j-2])/2 );
switch(j)
{
case 0: { break; }
case 1: { break; }
case 2: {
mean=(a[0]+a[1])/2;
a[0]=a[1];
a[1]=a[2];
j=1;
if (ampl > 0) {
*po++=ampl;
*po++=mean;
*po++=0.50;
}
break;
}
default: {
mean=(a[j-1]+a[j-2])/2;
a[j-2]=a[j];
j=j-2;
if (ampl > 0) {
*po++=ampl;
*po++=mean;
*po++=1.00;
cNr++;
}
break;
}
}
}
}
for (index=0; index<j; index++) {
ampl=fabs(a[index]-a[index+1])/2;
mean=(a[index]+a[index+1])/2;
if (ampl > 0){
*po++=ampl;
*po++=mean;
*po++=0.50;
}
}
/* you can free the allocated memeory */
/* for array_out data */
mxSetN(array_out, tot_num - cNr);
hs[0]=array_out;
}
Here's what happens:
Increment j by 1
assign to a[j] value pointed at by pr
increment pr.
In this order.
You specifically asked about:
a[++j]=*pr++;
j is being incremented before the assignment. In python the left hand side would be:
a[j+1]
and you would also then need to increment j before you use it next:
j += 1
The right hand side simply accesses the current position and then increments the position in the array. In python you would probably just use an iterator for your array.
BTW, you might find it difficult to do a line-by-line 'translation' of the code. I would suggest writing down the steps of the algorithm and then tackling it fresh in python, if that is what you need.
In Python, there aren't pointers, so how you translate this will depend on how you decide to represent pr. If you think of the pointer as a copy of the list pr = array_ext[:], the line you've highlighted would be something like
j = j + 1
a[j] = pr.pop(0)
For greater efficiency (and a closer parallel to what the C code is doing), you could use pr as an index into the list array_ext, starting it at 0. Then, the line you highlighted does this:
j = j + 1
a[j] = array_ext[pr]
pr = pr + 1
I'm writing a program with java that analyses stock data.
I almost got it working but now it gives me an ArrayOutOfBounds Exception.
int n = closingPrices.size();
double[][] cParray = new double[n][1];
for(int i = 0; i < n; i++)
{
cParray[i][1] = closingPrices.get(i);
}
I hope you can give me help on how to solve this problem..
the size of cParray[i] is 1. It can have only one element with the index [0]
so try cParray[i][0] = closingPrices.get(i)
OR double[][] cParray = new double[n][2]
I started trying to use rcpp to improve the speed of a for loop in R where each iteration depends on the previous (i.e. no easy vectorization). My current code (below) is a bit faster than R but no nearly as fast as I would have thought. Any glaring inefficiencies in the code below that someone can spot? Any general (or specific) advice would be helpful.
UpdateInfections <- cxxfunction(signature(pop ="data.frame",inds="integer",alpha="numeric",t="numeric"), '
DataFrame DF(pop);
IntegerVector xinds(inds);
NumericVector inf_time = DF["inf.time"];
IntegerVector loc = DF["loc"] ;
IntegerVector Rind = DF["R.indiv"] ;
NumericVector infector = DF["infector"] ;
IntegerVector vac = DF["vac"] ;
NumericVector wts(loc.size());
double xt = Rcpp::as<double>(t);
double xalpha = Rcpp::as<double>(alpha);
RNGScope scope; // Initialize Random number generator
Environment base("package:base");
Function sample = base["sample"];
int n = loc.size();
int i;int j;int k;
int infsize = xinds.size();
for (i=0;i<infsize;i++) {
int infpoint = xinds[i]-1;
NumericVector inf_times_prop(Rind[infpoint]);
NumericVector inf_me(Rind[infpoint]);
for (j=0; j<n;j++){
if (j == infpoint){
wts[j] = 0.0;
} else if (loc[j] == loc[infpoint]){
wts[j] = 1.0;
} else {
wts[j] = xalpha;
}
}
inf_me = sample(n,Named("size",Rind[infpoint]),Named("prob",wts));
//Note that these will be shifted by one
for (k=0;k<Rind[infpoint];k++){
inf_times_prop[k] = floor(::Rf_rlnorm(1.6,.6) + 0.5 + xt);
if (inf_times_prop[k] < inf_time[inf_me[k]-1] && vac[inf_me[k]-1] == 0){
inf_time[inf_me[k]-1] = inf_times_prop[k];
infector[inf_me[k]-1] = inf_me[k];
}
}
}
// create a new data frame
Rcpp::DataFrame NDF =
Rcpp::DataFrame::create(Rcpp::Named("inf.time")=inf_time,
Rcpp::Named("loc")=loc,
Rcpp::Named("R.indiv")=Rind,
Rcpp::Named("infector")=infector,
Rcpp::Named("vac")=vac);
return(NDF);
' , plugin = "Rcpp" )
We're actually working on a pure C++ sample function for RcppArmadillo right now. Take a look here http://permalink.gmane.org/gmane.comp.lang.r.rcpp/4179 or here http://permalink.gmane.org/gmane.comp.lang.r.rcpp for updates.
You are calling back to R. That cannot be as fast a pure C++ solution.
Your example is also long, too long. I recommend profiling and optimizing individual pieces. There is, alas, still no entirely free lunch.
I am trying to implement Distance Vector Routing algorithm, using http://www.cs.bu.edu/fac/byers/courses/791/F99/scribe_notes/cs791-notes-990923.html
(in C++).
Here is what I have done so
far:
i) Read no. of nodes.
ii) Implement the points 1 to 4 in the article as:
for(i = 0; i < nodes; i++) //nodes is the no. of nodes
{
for(j = 0; j < nodes; j++)
{
if(distanceVector[i][j] != 0) //distanceVector holds the cost value between every pair of links, 0 if no link exists
{
for(k = 0; k < nodes; k++)
{
if((distanceVector[i][j] + distanceVector[j][k]) < distanceVector[i][k])
{
distanceVector[i][k] = distanceVector[i][j] + distanceVector[j][k];
via[i][j] = i; // intermediate node, in case no link exists
via[j][i] = j;
}
}
}
}
}
I get the same array / matrix as it is. I have also tried juggling i, j, and k, but of no use.
Am I right in my implementation...???
Two things bother me about your code. First, you are using "0" to represent "no link". This can get you in trouble. The code basically read as follows: "if there is an intermediary point j, that makes that path from i to k shorter, change the path from i to k to pass via k". Therefore, using "0" to represent "no link" might make your code choose wrong "via"s. Try instead to use infinity (if you are using floating point) or a really big value (e.g., MAX_INT).
Second, these lines look wrong:
via[i][j] = i; // intermediate node, in case no link exists
via[j][i] = j;
Since you found a path from i to k via j that is shorter, it should be:
via[i][k] = j; // intermediate node, in case no link exists
via[k][i] = j;