Matlab incorrect sum value - matlab

In Matlab, I have a vector res of size 1*10.
Also, I have this code:
disp("Matrix:");
disp(res);
disp("Size:");
disp(size(res));
disp("Sum of elements:");
disp(sum(res));
Which outputs:
Matrix:
1.0e+05 *
1.9183 1.6247 1.5875 1.6979 1.3663 1.6511 1.5198 1.3014 1.2067 1.3661
Size:
1 10
Sum of elements:
1.5240e+06
1. What is 1.0e+05 *?
2. How can the sum of 1.9183 1.6247 1.5875 1.6979 1.3663 1.6511 1.5198 1.3014 1.2067 1.3661 be 1.5240e+06?
What I did so far:
I tried to see if there is a name conflict with whos ('res') but no other variable with the same name is in context.
I also tried to eliminate other sum name in context with clear sum but still I get the same result.

The Following notation:
Matrix:
1.0e+05 *
1.9183 1.6247 1.5875 1.6979 1.3663 1.6511 1.5198 1.3014 1.2067
means:
Matrix:
191830 162470 158750 169790 136630 165110 151980 130140 120670
it is a scientific notation to show the result in a standard format. Therefore, the problem of summing is solved by this description.

Related

Efficient method to query percentile in a list

I've come across the requirement to collect the percentiles from a list a few times:
Within what percentile is a certain number?
What is the nth percentile in a list?
I have written these methods to solve the issue:
/for 1:
percentileWithinThreshold:{[threshold;list] (100 * count where list <= threshold) % count list};
/for 2:
thresholdForPercentile:{[percentile;list] (asc list)[-1 + "j"$((percentile % 100) * count list)]};
They work well for both use cases, but I was thinking this is a too common use case, so probably Q offers already something out of the box that does the same. Any idea if there already exists something else?
'100 xrank' generates percentiles.
q) 100 xrank 1 2 3 4
q) 0 25 50 75
Solution for your second requirement:
q) f:{ y (100 xrank y:asc y) bin x}
Also, note that your second function result will not be always same as xrank. Reason for that is 'xrank' uses floor for fractional index output which is the normal scenario with calculating percentiles and your function round up the value and subtracts -1 which ensures that output will always be lesser-equal to input percentile. For example:
q) thresholdForPercentile[63;til 21] / output 12
q) f[63;til 21] / output 13
For first requirement, there is no inbuilt function. However you could improve your function if you keep your input list sorted because in that case you could use 'bin' function which runs faster on big lists.
q) percentileWithinThreshold:{[threshold;list] (100 * 1+list bin threshold) % count list};
Remember that 'bin' will throw type error if one argument is of float type and other is an integer. So make sure to cast them correctly inside the function.
qtln:{[x;y;z]cf:(0 1;1%2 2;0 0;1 1;1%3 3;3%8 8) z-4;n:count y:asc y;?[hf<1;first y;last y]^y[hf-1]+(h-hf)*y[hf]-y -1+hf:floor h:cf[0]+x*n+1f-sum cf}
qtl:qtln[;;8];

scala return matrix of average pixels

Here's the thing: I want to modify (and then return) a matrix of integers that is given in the parameters of the function. The funcion average (of the class MatrixMotionBlur) gives the average between the own pixel, upper, down and left pixels. Follows the following formula:
result(x, y) = (M1(x, y)+M1(x-1, y)+M1(x, y-1)+M1(x, y+1)) / 4
This is the code i've implemented so far
MatrixMotionBlur - Average function
MotionBlurSingleThread - run
The objetive here is to apply "average" method to alter the matrix value and return that matrix. The thing is the program gives me error when I to insert the value on the matrix.
Any ideas how to do this ?
The functional way
val updatedData = data.map{ outter =>
outter(i).map{ inner =>
mx.average(i.j)
}
}
Pay attention that Seq is immutable collection type and you can't just modify it, you can create new, modified collection only.
By the way, why you iterate starting 1, but not 0. Are you sure you want it?

Save outputs of nested for loops in MATLAB

I have the following codes which I wish to have an output matrix Rpp of (10201,3). I run this code (which takes a bit long) then I check the matrix size of Rpp and I see (1,3), I tried so many things I couldn't find any proper way. The logic of the codes is to take the 6 values (contain 4 constant values and 2 variable values (chosen from 101 values)) and make the calculation for 3 different i1 and store every output vector of 3 in a matrix with (101*101 (pairs of those 2 variable values)) rows and 3 (for each i1) columns.
I appreciate your help
Vp1=linspace(3000,3500,101);
Vp2=3850;
rho1=2390;
rho2=2510;
Vs1=linspace(1250,1750,101);
Vs2=2000;
i1=[10 25 40];
Rpp = zeros(length(Vp1)*length(Vs1),length (i1));
for n=1:length(Vp1)*length(Vs1)
for m=1:length (i1)
for l=1:length(Vp1)
for k=1:length(Vs1)
p=sin(i1)/Vp1(l);
i2=asin(p*Vp2);
j1=asin(p*Vs1(k));
j2=asin(p*Vs2);
a=rho2*(1-2*Vs2^2*p.^2)-rho1*(1-2*Vs1(k).^2*p.^2);
b=rho2*(1-2*Vs2^2*p.^2)+2*rho1*Vs1(k)^2*p.^2;
c=rho1*(1-2*Vs1(k)^2*p.^2)+2*rho2*Vs2^2*p.^2;
d=2*(rho2*Vs2^2-rho1*Vs1(k)^2);
E=b.*cos(i1)./Vp1(l)+c.*cos(i2)/Vp2;
F=b.*cos(j1)./Vs1(k)+c.*cos(j2)/Vs2;
G=a-d*(cos(i1)/Vp1(l)).*(cos(j2)/Vs2);
H=a-d*(cos(i2)/Vp2).*(cos(j1)/Vs1(k));
D=E.*F+G.*H.*p.^2;
Rpp=((b.*(cos(i1)/Vp1(l))-c.*cos((i2)/Vp2)).*F-(a+d*((cos(i1)/Vp1(l))).*(cos(j2)/Vs2)).*H.*p.^2)./D
end
end
end
end
Try this. You 2 outer loops didn't do anything. You never used m or n so I killed those 2 loops. Also you just kept overwriting Rpp on every loop so your initialization of Rpp didn't do anything. I added an index var to assign the results to the equation to what I think is the correct part of Rpp.
Vp1=linspace(3000,3500,101);
Vp2=3850;
rho1=2390;
rho2=2510;
Vs1=linspace(1250,1750,101);
Vs2=2000;
i1=[10 25 40];
Rpp = zeros(length(Vp1)*length(Vs1),length (i1));
index = 1;
for l=1:length(Vp1)
for k=1:length(Vs1)
p=sin(i1)/Vp1(l);
i2=asin(p*Vp2);
j1=asin(p*Vs1(k));
j2=asin(p*Vs2);
a=rho2*(1-2*Vs2^2*p.^2)-rho1*(1-2*Vs1(k).^2*p.^2);
b=rho2*(1-2*Vs2^2*p.^2)+2*rho1*Vs1(k)^2*p.^2;
c=rho1*(1-2*Vs1(k)^2*p.^2)+2*rho2*Vs2^2*p.^2;
d=2*(rho2*Vs2^2-rho1*Vs1(k)^2);
E=b.*cos(i1)./Vp1(l)+c.*cos(i2)/Vp2;
F=b.*cos(j1)./Vs1(k)+c.*cos(j2)/Vs2;
G=a-d*(cos(i1)/Vp1(l)).*(cos(j2)/Vs2);
H=a-d*(cos(i2)/Vp2).*(cos(j1)/Vs1(k));
D=E.*F+G.*H.*p.^2;
Rpp(index,:)=((b.*(cos(i1)/Vp1(l))-c.*cos((i2)/Vp2)).*F-(a+d*((cos(i1)/Vp1(l))).*(cos(j2)/Vs2)).*H.*p.^2)./D;
index = index+1;
end
end
Results:
>> size(Rpp)
ans =
10201 3
The way you use the for loop is wrong. You're running the calculation for length(Vp1)*length(Vs1) * length (i1) * length(Vp1) * length(Vs1) times. Here's the correct way. I changed l into lll just so I won't confuse it with the number 1. In each iteration of the first for loop, you're running length(Vs1) times, and you need to assign the result (a 1X3 array) to the Rpp by using a row number specified by k+(lll-1)*length(Vp1).
for lll=1:length(Vp1)
for k=1:length(Vs1)
p=sin(i1)/Vp1(lll);
i2=asin(p*Vp2);
j1=asin(p*Vs1(k));
j2=asin(p*Vs2);
a=rho2*(1-2*Vs2^2*p.^2)-rho1*(1-2*Vs1(k).^2*p.^2);
b=rho2*(1-2*Vs2^2*p.^2)+2*rho1*Vs1(k)^2*p.^2;
c=rho1*(1-2*Vs1(k)^2*p.^2)+2*rho2*Vs2^2*p.^2;
d=2*(rho2*Vs2^2-rho1*Vs1(k)^2);
E=b.*cos(i1)./Vp1(lll)+c.*cos(i2)/Vp2;
F=b.*cos(j1)./Vs1(k)+c.*cos(j2)/Vs2;
G=a-d*(cos(i1)/Vp1(lll)).*(cos(j2)/Vs2);
H=a-d*(cos(i2)/Vp2).*(cos(j1)/Vs1(k));
D=E.*F+G.*H.*p.^2;
Rpp(k+(lll-1)*length(Vp1),:)=((b.*(cos(i1)/Vp1(lll))-c.*cos((i2)/Vp2)).*F-(a+d*((cos(i1)/Vp1(lll))).*(cos(j2)/Vs2)).*H.*p.^2)./D;
end
end

find value in a string of cell considering some margin

Suppose that I have a string of values corresponding to the height of a group of people
height_str ={'1.76000000000000';
'1.55000000000000';
'1.61000000000000';
'1.71000000000000';
'1.74000000000000';
'1.79000000000000';
'1.74000000000000';
'1.86000000000000';
'1.72000000000000';
'1.82000000000000';
'1.72000000000000';
'1.63000000000000'}
and a single height value.
height_val = 177;
I would like to find the indices of the people that are in the range height_val +- 3cm.
To find the exact match I would do like this
[idx_height,~]=find(ismember(cell2mat(height_str),height_val/100));
How can I include the matches in the previous range (174-180)?
idx_height should be = [1 5 6 7]
You can convert you strings into an numeric array (as #Divakar mentioned) by
height = str2num(char(height_str))*100; % in cm
Then just
idx_height = find(height>=height_val-3 & height<=height_val+3);
Assuming that the precision of heights stays at 0.01cm, you can use a combination of str2double and ismember for a one-liner -
idx_height = find(ismember(str2double(height_str)*100,[height_val-3:height_val+3]))
The magic with str2double is that it works directly with cell arrays to get us a numeric array without resorting to a combined effort of converting that cell array to a char array and then to a numeric array.
After the use of str2double, we can use ismember as you tried in your problem to get us the matches as a logical array, whose indices are picked up with find. That's the whole story really.
Late addition, but for binning my first choice would be to go with bsxfun and logical operations:
idx_height = find(bsxfun(#le,str2double(height_str)*100,height_val+3) & ...
bsxfun(#ge,str2double(height_str)*100,height_val-3))

How to use interp1 in matlab

I have the data
x=[14.0716101600000 17.7292101600000 21.3868101600000 21.3868101600000 25.0444101600000 28.7020101600000 32.3596101600000 36.0172101600000 39.6748101600000 43.3324101600000 46.9900101600000 50.6476101600000 54.3052101600000 57.9628101600000 61.6204101600000 65.2780101600000 68.9356101600000 72.5932101600000 76.2508101600000 79.9084101600000 83.5660101600000 87.2236101600000]
y=[0 0 0 0.152400000000000 0.152400000000000 0.533400000000000 0.685800000000000 0.838200000000000 0.990600000000000 1.14300000000000 1.14300000000000 1.14300000000000 1.29540000000000 1.44780000000000 1.60020000000000 1.75260000000000 1.90500000000000 2.05740000000000 2.20980000000000 2.36220000000000 2.51460000000000 2.66700000000000]
new_x=[21.38,25.03,28.70,32.33,35.99,39.55,45.13,48.80,54.38,58.05];
However, when I use interp1 like
new_y = interp1(x,y,new_x);
it doesn't work.Please tell me why.Thank you so much!
The x vector must be strictly monotonic. In your data, third and fourth elements of x are equal. If you remove, say, fourth element from x and y by
x(4)=[];
y(4)=[];
it works without problem.