matlab : Inserting elements in array - matlab

This is really basic question. I have an array "relevant_IDs". I need to store 1 to 100 values in it when variable category is 1. Similarly, 101 to 200 when category is 2. So on till 901 to 1000 when category is 10.
I have written code for it but it is not inserting 100 values in it.
Code:
for i=1: 1000
if(category==1 && i>0 && i< 101)
relevant_IDs(i) = i;
end
if(category==2 && i>100 && i< 201)
relevant_IDs(i) = i;
end
if(category==3 && i>200 && i< 301)
relevant_IDs(i) = i;
end
if(category==4 && i>300 && i< 401)
relevant_IDs(i) = i;
end
if(category==5 && i>400 && i< 501)
relevant_IDs(i) = i;
end
if(category==6 && i>500 && i< 601)
relevant_IDs(i) = i;
end
if(category==7 && i>600 && i< 701)
relevant_IDs(i) = i;
end
if(category==8 && i>700 && i< 801)
relevant_IDs(i) = i;
end
if(category==9 && i>800 && i< 901)
relevant_IDs(i) = i;
end
if(category==10 && i>900 && i< 1001)
relevant_IDs(i) = i;
end
end

Something like this should work and be much quicker:
relevant_IDs = (category - 1) * 100 + (1:100);

You could also just generate the whole thing (numbers from 1 to 1000), then index into the matrix using category value as index to get the desired relevant_IDs:
relevant_IDs = reshape(1:1000, [100,10]).';
relevant_IDs(category,:) % this will return a 1x100 row vector
% (category is a number from 1 to 10)

Related

How to fill only the internal section of a shell with MATLAB

I'm writing a script to process .png images similar to how 3D printing slicers work.
I need to fill the inside of the objects 'shell' but not gaps in the shell itself.
First I tried using MATLAB imfill function which gets me 90% of the way but runs into trouble if there's a internal wall or gap, in that case it fills the shell and the gap as well. (image 2).
I then tried a set of if statements that fill based on encountering walls moving along the image, filling after every other wall encountered. This works except for when it encounters a wall that doesn't have a void after it like a long side wall, (image 3).
My desired result is in image 4. That was done with a manual imfill but the image sets I want to process are in the thousands so an automated method is nearly essential.
%method 1
solid = imfill(im);
%method 2
% im aware this code is bad and full of redundant checks and conditions
% it was written as a fast check to see if what i believed the failure would
% be was correct which it sadly was. I'm not as interested in the content
% (I can fix that myself) as I am the general outcome.
slick = imread('image.png');
solid_im = zeros(size(slick));
for kx=1:x
last=0;
is_filling = 0;
for ky =1:y
if slick(kx,ky) == 1 && last == 0 && is_filling == 0
solid_im(kx,ky) = 1;
last = 1;
is_filling = 1;
elseif slick(kx,ky) == 1 && last == 1 && is_filling == 0
solid_im(kx,ky) = 1;
elseif slick(kx,ky) == 0 && last == 1 && is_filling == 0
solid_im(kx,ky) = 0;
last = 0;
elseif slick(kx,ky) == 0 && last == 0 && is_filling ==0
solid_im(kx,ky) = 0;
elseif slick(kx,ky) == 1 && last == 0 && is_filling == 1
solid_im(kx,ky)= 1;
last = 1;
is_filling = 0;
elseif slick(kx,ky) == 1 && last == 1 && is_filling == 1
solid_im(kx,ky) = 1;
elseif slick(kx,ky) == 0 && last == 1 && is_filling == 1
solid_im(kx,ky) = 1;
last = 0;
elseif slick(kx,ky) == 0 && last == 0 && is_filling == 1
solid_im(kx,ky) = 1;
end
end
end
Image with only shell walls:
Completely filled with imfill:
Image filled by algorithm with bad lines:
Correctly filled image:
Looks like a an old answer of mine solves the problem:
Refer to: How can I fill between edges of these characters in matlab?
Here is the code:
I = imread('https://i.stack.imgur.com/6Rdl1.png');
I = imbinarize(rgb2gray(I));
J1 = imfill(I, 'holes');
J2 = imfill(I, [1, 1]);
J3 = imfill(~J2, [1, 1]);
J4 = imfill(~J3, 'holes');
J5 = J1 & (~J4);
figure;imshow(J5)
Result:
I can't guarantee the solution is going to work for thousands of images.

Controlling vector tile zoom

Is there any way to define the {z} variable in the vector tiles portion of the script on the fly based on zoom? I want to define different numbers for each zoom than the default mapbox {z}:
map.addSource('PWS', {
type: 'vector',
tiles: ['//features.mvt?x={x}&y={y}&z={z}&apiKey={akey}&tile-size=512&time='+time[0]+'&time='+time[1]+'&time='+time[2]+'&time='+time[3]+'&stepped=true'],
tileSize: 512,
});
I have tried using this method, and it works OK, but it has a hard time with cached tiles...
map.on('zoomend', function() {
zm = map.getZoom();
if (zm > 0 && zm < 2){
zoomM = 4;
}
else if (zm >= 2 && zm < 3){
zoomM = 4;
}
else if (zm >= 3 && zm < 4){
zoomM = 4;
}
else if (zm >= 4 && zm < 5){
zoomM = 4;
}
else if (zm >= 5 && zm < 6){
zoomM = 5;
}
else if (zm >= 6 && zm < 7){
zoomM = 7;
}
else if (zm >= 7 && zm < 8){
zoomM = 8;
}
else if (zm >= 8 && zm < 9){
zoomM = 9;
}
else if (zm >= 9 && zm < 10){
zoomM = 10;
}
else if (zm >= 10 && zm < 11){
zoomM = 11;
}
else {
zoomM = 12;
}
console.log(zoomM,zm);
const source = map.getSource('PWS');
source.tiles = ['//features.mvt?x={x}&y={y}&z='+zoomM+'&apiKey={akey}&tile-size=512&time='+pwstime[0]+'&time='+pwstime[1]+'&time='+pwstime[2]+'&time='+pwstime[3]+'&stepped=true'];
map.style.sources['PWS'].reload();
});
There has got to be a better way to do this...
I have also tried this: Recommended way to switch tile urls in mapbox-gl-js
And seen this: https://github.com/mapbox/mapbox-gl-js/issues/2941
Is there a reason why you can't use transformRequest to change the z on the fly as the tile requests are made?
https://www.mapbox.com/mapbox-gl-js/api/

An array for multiple LHS assignment cannot contain LEX_TS_STRING error

New to programing in matlab. I am currently trying to make a MATLAB program that will find the critical values of a multi-variable function and tell me whether each are a minimum, maximum, or saddle point. Unfortunately I always get the error : An array for multiple LHS assignment cannot contain LEX_TS_STRING
Any help will be very appreciated.
here's the code:
function [c,d] = critcalpoints(f)
syms x y
f(x,y)=x^3-3*x^2+5*x*y-7*y^2;
gradf = jacobian(f(x,y));
hessmatf = jacobian(gradf,[x,y]);
[xcr,ycr]=solve(gradf(1),gradf(2));
H1=subs(hessmatf,[x,y],[xcr(1),ycr(1)]);
H2=subs(hessmatf,[x,y],[xcr(2),ycr(2)]);
eig(H1);
eig(H2);
c = double(eig(H1));
d = double(eig(H2));
if (c(1) > 0 && d(1) > 0) || (c(2) > 0 && d(2) > 0)
print([xcr,ycr],' is a minimum')
elseif (c(1) < 0 && d(1) < 0) || (c(2) < 0 && d(2) < 0)
print( [xcr, ycr], ' is a maximum')
elseif (c(1) < 0 && d(1) > 0) || (c(1) > 0 && d(1) < 0)
print( [xcr, ycr], ' is a saddle point')
elseif (c(2) < 0 && d(2) > 0) || (c(2) > 0 && d(2) < 0)
print( [xcr, ycr], ' is a saddle point')
elseif (c(1)==0 || d(1)==0)
print( [xcr, ycr], ' is degenerate')
elseif (c(2)==0 || d(2)==0)
print( [xcr, ycr], ' is degenerate')
end
Cannot reproduce your error. The code can work but you need to change print to something else as print doesn't do what you think it does. The print function prints a figure that is open to file. Change it so that you display xcr and ycr first then display the right condition to satisfy after. Use disp instead:
syms x y
f(x,y)=x^3-3*x^2+5*x*y-7*y^2;
gradf = jacobian(f(x,y));
hessmatf = jacobian(gradf,[x,y]);
[xcr,ycr]=solve(gradf(1),gradf(2));
H1=subs(hessmatf,[x,y],[xcr(1),ycr(1)]);
H2=subs(hessmatf,[x,y],[xcr(2),ycr(2)]);
eig(H1);
eig(H2);
c = double(eig(H1));
d = double(eig(H2));
disp([xcr, ycr]); % Display the solutions first
if (c(1) > 0 && d(1) > 0) || (c(2) > 0 && d(2) > 0)
disp('is a minimum')
elseif (c(1) < 0 && d(1) < 0) || (c(2) < 0 && d(2) < 0)
disp('is a maximum')
elseif (c(1) < 0 && d(1) > 0) || (c(1) > 0 && d(1) < 0)
disp('is a saddle point')
elseif (c(2) < 0 && d(2) > 0) || (c(2) > 0 && d(2) < 0)
disp('is a saddle point')
elseif (c(1)==0 || d(1)==0)
disp('is degenerate')
elseif (c(2)==0 || d(2)==0)
disp('is degenerate')
end
I get:
[ 0, 0]
[ 59/42, 295/588]
is a maximum

free() and mxFree() in MATLAB - freeing memory twice

Good day,
I have the following code which has given me problems for a day already.
I have debugged it, and it works fine until trying to free the memory. The free() function should be called at the end of the execution automatically, so I commented the mxFree() code out, in hope of getting a result. Even if I do that, the program frees the memory twice, like in the case of manually freeing memory - and thus I conclude that it is beyond my control.
*** glibc detected *** /usr/local/MATLAB/R2012a/bin/glnx86/MATLAB: free(): invalid pointer: 0xad2427a1 ***
Is there something I missed?
Note: I have tried some examples of .mex files with memory allocation and they work fine - so the mistake is down below, in my code.
/*
Beamforming algorithm
Arguments: xr, yr, zr,
t, ts, W, U,
Sdata, NrSensor c, omega_o
Output: S1_sum
S1_sum = beamforming(xr,yr,zr,t,ts,W,U,Sdata,NrSensor,c,omega_o)
*/
#include "mex.h"
#include <stdlib.h>
#include <math.h>
#define INPUT_ARGS 11
#define OUTPUT_ARGS 1
#define Ar(a, b) Ar[b+a*NrSensor]
#define Ai(a, b) Ai[b+a*NrSensor]
#define V(a, b) V[b+a*len_zr]
#define tau(a, b) tau[b+a*NrSensor]
#define tau_s(a, b) tau_s[b+a*len_zr]
#define tau_r(a, b) tau_r[b+a*NrSensor]
#define w(a, b) w[b+a*len_zr]
#define W(a, b) W[b+a*NrSensor]
#define arg(a, b) arg[b+a*len_zr]
#define newrange(a, b) newrange[b+a*len_zr]
#define oldrange(a, b) oldrange[b+a*len_zr]
#define S1_sum_r(a, b, c) S1_sum_r[c+b*len_xr+a*len_yr*len_xr]
#define S1_sum_i(a, b, c) S1_sum_i[c+b*len_xr+a*len_yr*len_xr]
#define Sdata_r(a, b) Sdata_r[b+a*NrSensor]
#define Sdata_i(a, b) Sdata_i[b+a*NrSensor]
#define S1interpr(a, b) S1interpr[b+a*len_zr]
#define S1interpi(a, b) S1interpi[b+a*len_zr]
#define PI_ 3.141592653
double sinc(double x){
return sin(PI_*x)/(PI_*x);
}
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
{
/*
Declarations
*/
int xr_, yr_, i, j, m;
int len_xr, len_yr, len_zr, len_t,
len_t_, NrSensor, NrSensor_Cen;
double _t, _i, arg_min, arg_max, norm_factor;
double start_tau, end_tau, c, omega_o;
double *xr, *yr, *zr, *t, *ts,
*Sdata_r, *Sdata_i, *W;
double *Ar, *Ai, *V, *tau, *tau_r, *tau_s,
*arg, *U, *w, *t_, *x_r, *x_i, *start_index,
*newrange, *oldrange, *S1_sum_r, *S1_sum_i,
*S1interpi, *S1interpr;
/*
Checking number of arguments
*/
if(nrhs != INPUT_ARGS)
mxErrMsgTxt("Incorrect number of arguments!\n");
if(nlhs != OUTPUT_ARGS)
mxErrMsgTxt("Incorrect number of outputs!\n");
/*
Reading arguments
*/
xr = mxGetPr(prhs[0]);
yr = mxGetPr(prhs[1]);
zr = mxGetPr(prhs[2]);
t = mxGetPr(prhs[3]);
ts = mxGetPr(prhs[4]);
W = mxGetPr(prhs[5]);
U = mxGetPr(prhs[6]);
Sdata_r = mxGetPr(prhs[7]);
Sdata_i = mxGetPi(prhs[7]);
NrSensor = (int) mxGetScalar(prhs[8]);
c = mxGetScalar(prhs[9]);
omega_o = mxGetScalar(prhs[10]);
len_xr = mxGetN(prhs[0]);
len_yr = mxGetN(prhs[1]);
len_zr = mxGetN(prhs[2]);
len_t = mxGetM(prhs[3]);
/*
Initialisations
*/
_t = 0.0;
len_t_ = 0;
NrSensor_Cen = NrSensor/2;
/*
Space allocation and checking
*/
arg = malloc(sizeof(double)*len_zr*len_t);
Ar = malloc(sizeof(double)*len_zr*NrSensor);
Ai = malloc(sizeof(double)*len_zr*NrSensor);
V = malloc(sizeof(double)*len_zr*3);
tau = malloc(sizeof(double)*len_zr*NrSensor);
tau_s = malloc(sizeof(double)*len_zr*3);
tau_r = malloc(sizeof(double)*len_zr*NrSensor);
U = malloc(sizeof(double)*3);
w = malloc(sizeof(double)*len_zr*3);
W = malloc(sizeof(double)*NrSensor*3);
ts = malloc(sizeof(double)*len_zr);
t = malloc(sizeof(double)*len_t);
t_ = malloc(sizeof(double)*len_t);
x_r = malloc(sizeof(double)*len_t);
x_i = malloc(sizeof(double)*len_t);
arg = malloc(sizeof(double)*len_zr*len_t);
newrange = malloc(sizeof(double)*len_zr*len_t);
oldrange = malloc(sizeof(double)*len_zr*len_t);
S1interpr = malloc(sizeof(double)*NrSensor*len_zr);
S1interpi = malloc(sizeof(double)*NrSensor*len_zr);
start_index = malloc(sizeof(double)*len_t);
/*
S1_sum_r = mxMalloc(len_xr*len_yr*len_zr);
S1_sum_i = mxMalloc(len_xr*len_yr*len_zr);
*/
int dim_S1_sum[3] = {len_xr, len_yr, len_zr};
plhs[0] = mxCreateNumericArray(3, dim_S1_sum,
mxDOUBLE_CLASS,
mxCOMPLEX);
S1_sum_r = (double*) mxGetPr(plhs[0]);
S1_sum_i = (double*) mxGetPi(plhs[0]);
if(arg == NULL ||
Ar == NULL ||
Ai == NULL ||
V == NULL ||
tau == NULL ||
tau_s == NULL ||
tau_r == NULL ||
U == NULL ||
W == NULL ||
w == NULL ||
ts == NULL ||
t == NULL ||
t_ == NULL ||
x_r == NULL ||
x_i == NULL ||
start_index == NULL ||
newrange == NULL ||
oldrange == NULL ||
S1_sum_r == NULL ||
S1_sum_i == NULL ||
S1interpr == NULL||
S1interpi == NULL){
mxErrMsgTxt("Malloc error!\n");
return;
}
/*
--- INITIALISING S1interp, S1_sum, tau, full of zeros
*/
for(i=0; i<NrSensor; i++){
for(j=0; j<len_zr; j++){
S1interpr(i,j) = 0;
S1interpi(i,j) = 0;
}
}
for(i=0; i<len_xr; i++){
for(j=0; j<len_yr; j++){
for(m=0; m<len_zr; m++){
S1_sum_r(i,j,m) = 0;
S1_sum_i(i,j,m) = 0;
}
}
}
for(i=0; i<NrSensor; i++){
for(j=0; j<len_zr; j++){
tau(i,j) = 0;
}
}
/*
--- MAIN ALGORITHM ---
*/
for(xr_=0; xr_ < len_xr; xr_++){
for(yr_=0; yr_ < len_yr; yr_++){
for(i=0; i < len_zr; i++){
V(0, i) = xr[xr_];
V(1, i) = yr[yr_];
V(2, i) = zr[i];
}
for(i=0; i < len_zr; i++){
tau_s(0, i) = V(0, i) - U[0];
tau_s(1, i) = V(1, i) - U[1];
tau_s(2, i) = V(2, i) - U[2];
}
for(m=0; m < NrSensor; m++){
for(i=0; i < len_zr; i++){
/*
I see no point of the squeeze function
since W is already of known sizes
*/
w(0, i) = V(0, i) - W(0, m);
w(1, i) = V(1, i) - W(1, m);
w(2, i) = V(2, i) - W(2, m);
}
for(i=0; i< len_zr; i++){
/*
sum(w.*w)
*/
_t = w(0, i)*w(0,i) +
w(1, i)*w(1,i) +
w(2, i)*w(2,i);
tau_r(m, i) = sqrt(_t)/c;
}
}
for(m=0; m < len_zr; m++){
for(i=0; i < NrSensor; i++){
/*
Computing sum(tau_s(m, :).*tau_s(m, :))
*/
_t = tau_s(0, m)*tau_s(0, m) +
tau_s(1, m)*tau_s(1, m) +
tau_s(2, m)*tau_s(2, m);
tau(i, m) = tau_r(i, m) + sqrt(_t)/c;
}
}
/*
for(i=0; i < len_zr; i++){
for(j=0; j < NrSensor; j++){
Tau(i,j)=tau(i,j);
}
}
*/
for(i=0; i < len_zr; i++){
for(j=0; j < NrSensor; j++){
Ar(i,j)=cos(omega_o * tau(i, j));
Ai(i,j)=sin(omega_o * tau(i, j));
}
}
/*
--- BIG LOOP AHEAD ---
*/
for(m=0; m < NrSensor; m++){
start_tau = tau(NrSensor_Cen, 1);
end_tau = tau(NrSensor_Cen, len_zr);
/*
Finding index : writing start indexes
and also t_ array
*/
len_t_=0;
for(i=0; i<len_t; i++){
if(t[i] >= start_tau &&
t[i] <= end_tau){
start_index[len_t_] = i;
t_[len_t_] = t[i];
x_r[len_t_] = Sdata_r(i, m);
x_i[len_t_] = Sdata_i(i, m);
len_t_++;
}
}
for(i=0; i < len_zr; i++){
ts[i]=tau(m, i);
}
for(i=0; i < len_t_; i++){
for(j=0; j < len_zr; j++){
newrange(i, j) = ts[j];
}
}
for(i=0; i < len_zr; i++){
for(j=0; j < len_t_; j++){
oldrange(j, i) = t_[j];
}
}
for(i=0; i < len_t_; i++){
for(j=0; j < len_zr; j++){
arg(i, j) = newrange(i, j)-oldrange(i, j);
}
}
arg_min = arg[0];
for(i=0; i < len_t_; i++)
for(j=0; j < len_zr; j++)
if(arg_min>arg(i, j))
arg_min=arg(i, j);
arg_max = arg[0];
for(i=0; i < len_t_; i++)
for(j=0; j < len_zr; j++)
if(arg_max<arg(i, j))
arg_max=arg(i, j);
norm_factor = (2*len_t_)/(arg_max-arg_min);
for(i=0; i < len_zr; i++){
_t = 0;
for(j=0; j < NrSensor; j++){
_t = sinc(arg(i, j)*norm_factor)*x_r[j];
}
S1interpr(m, i) = Ar(m, i) * _t;
_t = 0;
for(j=0; j < NrSensor; j++){
_t = sinc(arg(i, j)*norm_factor)*x_i[j];
}
S1interpi(m, i) = Ai(m, i) * _t;
}
}
for(i=0; i < len_zr; i++){
_t = 0;
for(j=0; j < NrSensor; j++){
_t += S1interpr(j, i);
}
S1_sum_r(xr_, yr_, i) = _t;
_t = 0;
for(j=0; j < NrSensor; j++){
_t += S1interpi(j, i);
}
S1_sum_i(xr_, yr_, i) = _t;
}
}
}
free(arg);
free(Ar);
free(Ai);
free(V);
free(tau);
free(tau_s);
free(tau_r);
free(U);
free(w);
free(W);
free(ts);
free(t);
free(t_);
free(x_r);
free(x_i);
free(newrange);
free(oldrange);
free(S1interpr);
free(S1interpi);
free(start_index);
return;
}
EDIT
I have deleted all my code except the beginning (up to the memory allocation) and the memory freeing. I'm also using malloc() and free() now. In between the memory allocation and freeing, I have also put this code:
for(i=0; i<NrSensor; i++){
for(j=0; j<len_zr; j++){
S1interpr(i,j) = 0;
S1interpi(i,j) = 0;
}
}
for(i=0; i<NrSensor; i++){
for(j=0; j<len_zr; j++){
tau(i,j) = 0;
}
}
The first loop causes no problem. The second one though, apparently corrupts the variable V (declared before it) and the one declared after it. And it seems, according to my logic, that it does not exceed any kind of bounds...
The second loop does not index correctly for tau. You are defining indexing for tau as
#define tau(a, b) tau[b+a*NrSensor]
Let us walk through the second loop assuming NrSensor = 10 and len_zr = 5. For this case max value of loop variable i is 9 and max value of loop variable j is 4. Now,
tau(9,4) => tau[4+9*10] => tau[94].
But you are allocating tau with
tau = malloc(sizeof(double)*len_zr*NrSensor);
which for the sample values 10 and 5 is
tau = malloc(sizeof(double)*50)
You either need to change the indexing definition for tau to swap a and b or change the order of loops i and j.

Where is the huge performance difference for the two versions of the code?

I am working on a problem that Given a string s, partitions s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s. The problem can also be found in here. https://oj.leetcode.com/problems/palindrome-partitioning-ii/
Version 1 is one version of solution I found online.
Version 2 is my code.
They both seem to work in very similar ways. However, with a reasonably large input, version 2 takes more than 6000 milliseconds whereas version 1 takes around 71 milliseconds.
Can anyone provide any idea where the time difference is from?
Version 1:
int minSol(string s) {
int len = s.size();
vector<int> D(len + 1);
vector<vector<int>> P;
for (int i = 0; i < len; i++){
vector<int> t(len);
P.push_back(t);
}
for (int i = 0; i <= len; i++)
D[i] = len - i;
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
P[i][j] = false;
for (int i = len - 1; i >= 0; i--){
for (int j = i; j < len; j++){
if (s[i] == s[j] && (j - i < 2 || P[i + 1][j - 1])){
P[i][j] = true;
D[i] = min(D[i], D[j + 1] + 1);
}
}
}
return D[0] - 1;
}
Version 2:
int minCut(string s) {
int size = s.size();
vector<vector<bool>> map;
for (int i = 0; i < size; i++){
vector<bool> t;
for (int j = 0; j < size; j++){
t.push_back(false);
}
map.push_back(t);
}
vector<int> minCuts;
for (int i = 0; i < size; i++){
map[i][i] = true;
minCuts.push_back(size - i - 1);
}
for (int i = size - 1; i >= 0; i--){
for (int j = size - 1; j >= i; j--){
if (s[i] == s[j] && (j - i <= 1 || map[i + 1][j - 1])){
map[i][j] = true;
if (j == size - 1){
minCuts[i] = 0;
}else if (minCuts[i] > minCuts[j + 1] + 1){
minCuts[i] = minCuts[j + 1] + 1;
}
}
}
}
return minCuts[0];
}
I would guess it's because in the second version you're doing size^2 push_back's, whereas in the first version you're just doing size push_back's.