Normalize vector in MATLAB with first value 100 - matlab

I have a vector:
0.02
-0.02
0
-0.02
-0.08
-0.05
-0.04
-0.1
0
0.05
0.05
0.05
0.08
0.04
How do I normalize this with the first value starting at 100?

Simply divide by the first element and multiply by 100:
a = [0.02 -0.02 0 -0.02 -0.08 -0.05 -0.04 -0.1 0 0.05 0.05 0.05 0.08 0.04]
b = a ./ a(1) * 100
b =
100 -100 0 -100 -400 -250 -200 -500 0 250 250 250 400 200

myArr = [0.02 -0.02 0 -0.02 -0.08 -0.05 -0.04 ...
-0.1 0 0.05 0.05 0.05 0.08 0.04]
myArr = 100*myArr/myArr(1)

Related

vectorise foor loop with a variable that is incremented in each iteration

I am trying to optimise the running time of my code by getting rid of some for loops. However, I have a variable that is incremented in each iteration in which sometimes the index is repeated. I provide here a minimal example:
a = [1 4 2 2 1 3 4 2 3 1]
b = [0.5 0.2 0.3 0.4 0.1 0.05 0.7 0.3 0.55 0.8]
c = [3 5 7 9]
for i = 1:10
c(a(i)) = c(a(i)) + b(i)
end
Ideally, I would like to compute it by writting:
c(a) = c(a) + b
but obviously it would not give me the same results since I have to recalculate the value for the same index several times so this way to vectorise it would not work.
Also, I am working in Matlab or Octave in case that this is important.
Thank you very much for any help, I am not sure that it is possible to be vectorise.
Edit: thank you very much for your answers so far. I have discovered accumarray, which I did not know before and also understood why changing the for loop between Matlab and Octave was giving me such different times. I also understood my problem better. I gave a too simple example which I thought I could extend, however, what if b was a matrix?
(Let's forget about c at the moment):
a = [1 4 2 2 1 3 4 2 3 1]
b =[0.69 -0.41 -0.13 -0.13 -0.42 -0.14 -0.23 -0.17 0.22 -0.24;
0.34 -0.39 -0.36 0.68 -0.66 -0.19 -0.58 0.78 -0.23 0.25;
-0.68 -0.54 0.76 -0.58 0.24 -0.23 -0.44 0.09 0.69 -0.41;
0.11 -0.14 0.32 0.65 0.26 0.82 0.32 0.29 -0.21 -0.13;
-0.94 -0.15 -0.41 -0.56 0.15 0.09 0.38 0.58 0.72 0.45;
0.22 -0.59 -0.11 -0.17 0.52 0.13 -0.51 0.28 0.15 0.19;
0.18 -0.15 0.38 -0.29 -0.87 0.14 -0.13 0.23 -0.92 -0.21;
0.79 -0.35 0.45 -0.28 -0.13 0.95 -0.45 0.35 -0.25 -0.61;
-0.42 0.76 0.15 0.99 -0.84 -0.03 0.27 0.09 0.57 0.64;
0.59 0.82 -0.39 0.13 -0.15 -0.71 -0.84 -0.43 0.93 -0.74]
I understood now that what I would be doing is rowSum per group, and given that I am using Octave I cannot use "splitapply". I tried to generalise your answers, but accumarray would not work for matrices and also I could not generalise #rahnema1 solution. The desired output would be:
[0.34 0.26 -0.93 -0.56 -0.42 -0.76 -0.69 -0.02 1.87 -0.53;
0.22 -1.03 1.53 -0.21 0.37 1.54 -0.57 0.73 0.23 -1.15;
-0.20 0.17 0.04 0.82 -0.32 0.10 -0.24 0.37 0.72 0.83;
0.52 -0.54 0.02 0.39 -1.53 -0.05 -0.71 1.01 -1.15 0.04]
that is "equivalent" to
[sum(b([1 5 10],:))
sum(b([3 4 8],:))
sum(b([6 9],:))
sum(b([2 7],:))]
Thank you very much, If you think I should include this in another question instead of adding the edit I will do so.
Original question
It can be done with accumarray:
a = [1 4 2 2 1 3 4 2 3 1];
b = [0.5 0.2 0.3 0.4 0.1 0.05 0.7 0.3 0.55 0.8];
c = [3 5 7 9];
c(:) = c(:) + accumarray(a(:), b(:));
This sums the values from b in groups defined by a, and adds that to the original c.
Edited question
If b is a matrix, you can use
full(sparse(repmat(a, 1, size(b,1)), repelem(1:size(b,2), size(b,1)), b))
or
accumarray([repmat(a, 1, size(b,1)).' repelem(1:size(b,2), size(b,1)).'], b(:))
Matrix multiplication and implicit expansion and can be used (Octave):
nc = numel(c);
c += b * (1:nc == a.');
For input of large size it may be more memory efficient to use sparse matrix:
nc = numel(c);
nb = numel(b);
c += b * sparse(1:nb, a, 1, nb, nc);
Edit: When b is a matrix you can extend this solution as:
nc = numel(c);
na = numel(a);
out = sparse(a, 1:na, 1, nc, na) * b;

How to solve problem linear programming Matlab

I am solving the following linear programming problem, I am guiding myself on the documentation
Documentation Matlab
Every time I execute I get the following error
Dimensions of matrices being concatenated are not consistent.
I have the objective function and restrictions as follows
%F.O
f=[0.669 0.654 0.503 0.683 0.670 0.673 0.749 0.655 0.660 0.583 1.243 0.639 2.024 2.156 1.672 0.473 0.139 0.687];
%Restrictions
Aeq=[0.1 0.12 0.335 0.15 0.18 0.19 0.12 0.15 0.15 0.15 0.15 0.11 0.13 0.46;
0.3 0.24 0.03 0.05 0.04 0.27 0.03 0.24 0.15 0.52 0.52;
0.1 0.12 0.31 0.15 0.19 0.08 0.2 0.12 0.15 0.50 0.34 0.44;
0.26 0.50;
0.06 0.17];
b=[285.71; 305.33; 450; 262.50; 41.50];
and I execute it with the following command
x=linprog(f,Aeq,b)
The restrictions take them out of the following exercise
Exercise
This should be the result of z
Result
A matrix must have the same number of columns in each row. Aeq in your case has different number of columns.
How to fix it?
The variables missing in the equations of constraints have zero coefficients. So:
%Objective Function
%X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18
f = [0.669 0.654 0.503 0.683 0.670 0.673 0.749 0.655 0.660 0.583 1.243 0.639 2.024 2.156 1.672 0.473 0.139 0.687];
A = []; b = []; %No inequality constraints
%Equality Constraints are:
%X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18
Aeq=[0.1 0.12 0.335 0.15 0.18 0.19 0.12 0.15 0.15 0.15 0 0.15 0.11 0 0.13 0 0 0.46; %Nitrogeno
0.3 0.24 0 0.03 0.05 0.04 0.27 0.03 0.24 0.15 0 0 0.52 0.52 0 0 0 0 ; %Fosforo
0.1 0.12 0 0.31 0.15 0.19 0.08 0.2 0.12 0.15 0.50 0 0 0.34 0.44 0 0 0 ; %Potasio
0 0 0 0 0 0 0 0 0 0 0 0.26 0 0 0 0 0.50 0 ; %Calcio
0 0 0 0 0.06 0 0 0 0 0 0 0 0 0 0 0.17 0 0]; %Magnesio
beq = [285.71; 305.33; 450; 262.50; 41.50]; %What you defined as 'b' is actually `beq`
lb = zeros(18,1); ub = inf(18,1); %Bounds
[x, Optimal_sol] = linprog(f, A, b, Aeq, beq, lb, ub);
>> x
x =
1.0e+03 *
0.7142
0
0
1.0268
0
0
0
0
0
0.4018
0
0
0
0
0
0.2441
0.5250
0
>> Optimal_sol
Optimal_sol =
1.6018e+03

sum specific columns in matlab vectorized

I have a big matrix lets say 100000x13.
I need to sum specific columns of this matrix.
For example:
matrix = [0.70 0.30 0 0 0.15 0.21 0.58 0.06 0.00 1.00 0 0 1.00;
0.70 0.00 0 0 0.00 0.00 0.07 0.06 0.00 0.80 0 0 1.00;
0.70 0.00 0 0 0.00 0.00 0.58 0.06 0.00 1.00 0 0 0.94];
inputVect = [4 4 3 2];
idx2 = cumsum(inputVect);
idx1 = [1 idx2(1:end-1)+1];
result = (1-sum(matrix(:,idx1(1):idx2(1)),2)) + (1-sum(matrix(:,idx1(2):idx2(2)),2))+(1-sum(matrix(:,idx1(3):idx2(3)),2)) + (1-sum(matrix(:,idx1(4):idx2(4)),2));
The thing is inputVect needs to be a function argument that I don't allways know the size. And because of the size of the matrix I should also avoid for loops. Any help would be much appreciated.

Varian in matlab applies multiple functions to input

I've understood the use of varfun in matlab. I need to apply mean and std to the grouped variables of this table.
N mut time
___ ___ ____
250 0.1 0.07
250 0.1 0.05
250 0.1 0.04
250 0.1 0.03
250 0.2 0.03
250 0.2 0.04
250 0.2 0.03
250 0.2 0.05
250 0.3 0.05
250 0.3 0.06
750 0.2 0.24
750 0.3 0.29
750 0.3 0.3
750 0.3 0.31
750 0.3 0.3
750 0.4 0.33
750 0.4 0.34
750 0.4 0.33
750 0.4 0.32
750 0.5 0.38
750 0.5 0.39
This table has two values of N and five different values of mut and I need to compute the average of time grouped by N and mut.
To do this I use the varfun function with the function handle #mean
Tgroup = varfun(#mean,T,'InputVariables','time','GroupingVariables',{'N','mut'})
and I get:
mut N GroupCount mean_time
___ ___ __________ _________
0.1 250 4 0.0475
0.2 250 4 0.0375
0.2 750 1 0.24
0.3 250 2 0.055
0.3 750 4 0.3
0.4 750 4 0.33
0.5 750 2 0.385
but now I also want to add a column that contains the standard deviation. To do this I create a anonymous function
func = #(x)[mean(x), std(x)]
and I use it in varfunc
varfun(#(x)[mean(x),std(x)],([T(1:5:50,:);T(400:5:450,:)]),'InputVariables','time','GroupingVariables',{'mut','N'})
Unfortunately I get this:
ans =
mut N GroupCount Fun_time
___ ___ __________ ___________________
0.1 250 4 0.0475 0.017078
0.2 250 4 0.0375 0.0095743
0.2 750 1 0.24 0
0.3 250 2 0.055 0.0070711
0.3 750 4 0.3 0.008165
0.4 750 4 0.33 0.008165
0.5 750 2 0.385 0.0070711
where the last column 'Fun_time' contains two sub columns, the first being the mean of grouped times, the second the standard deviation of grouped times.
How can I split these two columns directly using an anonymous function? This is very similar to what is done in R with the plyr package.
You could use dplyr to simplify the process
DF = read.table(text="
N mut time
250 0.1 0.07
250 0.1 0.05
250 0.1 0.04
250 0.1 0.03
250 0.2 0.03
250 0.2 0.04
250 0.2 0.03
250 0.2 0.05
250 0.3 0.05
250 0.3 0.06
750 0.2 0.24
750 0.3 0.29
750 0.3 0.3
750 0.3 0.31
750 0.3 0.3
750 0.4 0.33
750 0.4 0.34
750 0.4 0.33
750 0.4 0.32
750 0.5 0.38
750 0.5 0.39",header=TRUE)
newDF = DF %>%
group_by(N,mut) %>%
summarise(count = n(),meanTime = mean(time),sdTime = sd(time) ) %>%
as.data.frame()
# > newDF
# N mut count avgTime avgSD
#1 250 0.1 4 0.0475 0.017078251
#2 250 0.2 4 0.0375 0.009574271
#3 250 0.3 2 0.0550 0.007071068
#4 750 0.2 1 0.2400 NaN
#5 750 0.3 4 0.3000 0.008164966
#6 750 0.4 4 0.3300 0.008164966
#7 750 0.5 2 0.3850 0.007071068

Rescale signal 1 by following signal 2 matlab

Let say I have
A = [0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 1 1 1 1 1 ]
B = [0.01 0.02 0.01 0.03 0.04 0.05 0.07 0.04 0.03 0.01 0.01 0.03 0.04 0.03 0.02 0.01 0.011 0.02 0.03 0.04 0.05 0.04 0.01]
How can I rescale A follow maximum number of B.
The result should be
C = [0 0 0 0 0.07 0.07 0.07 0.07 0.07 0 0 0.04 0.04 0.04 0.04 0 0 0 0.05 0.05 0.05 0.05 0.05]
You can use accumarray like so:
subs = cumsum([diff(A) > 0, 0]).*A + 1; %//Similar to bwlabel if you have the image processing toolbox...
maximums = accumarray(subs(:), B(:), [], #max);
maximums(1) = 0;
C = maximums(subs)
Is it what you want to do?
C = A*max(B)/max(A)