MATLAB how to apply a function to cell arrays - arrays

I have the following cell array:
<20x2>
<32x2>
<28x2>
<30x2>
What I am trying to do is read into row 1 of the cell array which is <20x2> and once I am in <20x2> I would like to apply the following function to the first column only.
In the first one I would like every row of column 1 in C{1,1} to be subtracted by 0.1. In the second one C{2,1} (<32x2>) I would like every row of column 1 to be subtracted by 0.2 and so on...
So to clarify I am trying to subtract n*0.1 from the first column of each submatrix in the cell array where n= row number of the cell array. So if there was a section in the cell array in row 8, column 1 would be subtracted by 8*0.1 = 0.8
I hope the question is clear enough, I have tried to word it as clear as I can.
Thanks in advance for any help/suggestions
Attempt
First = C{1,1}(:,1);
Subtraction = First - 0.1
Gives me my desired result but only for row 1 of my cell array.
Unique question to Applying function to vectors row by row because this involves a cell array as opposed to a matrix. The aspect of reading into a cell array makes it a different variant of the problem so if somebody was having a similar problem to this question the mentioned 'duplicate' question would not help, especially with little MATLAB knowledge like myself

It is very easy to adapt your attempt to a loop:
for n = 1:size(c,1)
C{n,1}(:,1) = C{n,1}(:,1) - n*0.1;
end

Related

Converting Rows into Columns in a cell array in MATLAB

I have a 99x1 cell array and I would like to convert it into a 33x3 cell array for example.
I would like the first 3 rows of the 99x1 cell array to make up the first row in the 33x3 cell array and then the 3rd through 6th row in the 99x1 cell array to make up the second row in the 33x3 cell array.
I also need the data when being reshaped to go over column by column before it goes down. For example I would need:
1
2
3
4
to become
1, 2; 3, 4
not
1, 3; 2, 4
Help with this would be greatly appreciated
You can simply use the reshape-function. Since reshape(yourcell,[],3) would first fill the first column and then the second and so on instead of row-wise, you will need to combine it with the transpose operator .':
newcell=reshape(yourcell,3,[]).'
This way, you will first create a 3x33 cell using the reshape and then transform it into the desired 33x3 cell. The [] tells reshape to create as many columns as needed.

array based sumif in excel by formula

So I m trying to find some alternative to sumifs in excel where each condition needs to be checked in a 2D range instead of a 1D range.
For example, in the below table I want the sum of values in column V for rows where A12 ("IJ") is present in range A2:C8 (P), B12 ("NM") is present in the range D2:F8 (S) and C12 ("XX") is present in range G2:I8 (A)
I am trying to find a solution involving an array-based formula (without VBA).
Like for example in the below-given formulas,
SUMPRODUCT((B2:B8'=A12)*J2:J8) will give an array-based calculation as follows
SUMPRODUCT({TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE}*{22;79;45;67;43;72;52})
= SUMPRODUCT({22;0;45;0;0;72;0})
=139
It is easy when there is only one condition needs to be checked but like sumifs, I intend to check multiple conditions, but as soon as I add other conditions, the array becomes multidimensional and gives the wrong answer.
Example:
SUMPRODUCT((A2:C8=A12)*(D2:F8=B12)*J2:J8) breaks down to
=SUMPRODUCT(
{FALSE,TRUE,FALSE;FALSE,FALSE,FALSE;FALSE,TRUE,FALSE;FALSE,FALSE,FALSE;FALSE,FALSE,FALSE;FALSE,TRUE,FALSE;FALSE,FALSE,FALSE}*
{TRUE,FALSE,FALSE;FALSE,FALSE,FALSE;TRUE,FALSE,FALSE;FALSE,FALSE,FALSE;FALSE,FALSE,FALSE;TRUE,FALSE,FALSE;FALSE,FALSE,FALSE}
*J2:J8)
in the background what is happening is (example for 3rd row)
SUMPRODUCT( ({FALSE, TRUE ,FALSE} * {TRUE,FALSE,FALSE}) * 45 )
= SUMPRODUCT({FALSE,FALSE,FALSE} *45 )
=0
SUMPRODUCT(({FALSE,TRUE ,FALSE} + {TRUE,FALSE,FALSE}) * 45 )
= SUMPRODUCT({TRUE,TRUE,FALSE} *45 )
= 90
#expected answer =45
Can someone help me understand where I am going wrong or what I am missing?
If there is any other way then suggestions are always welcome.
Please note this is a dummy data actual data is very big for each header (P,S,A) there are values in 10 columns respectively and the number of rows is also very large.
Try this...
=SUMPRODUCT( ((A2:A8=A12)+(B2:B8=A12)+(C2:C8=A12)) * ((D2:D8=B12)+(E2:E8=B12)+(F2:F8=B12)) * ((G2:G8=C12)+(H2:H8=C12)+(I2:I8=C12)) * J2:J8 )
For SUMPRODUCT to work, the shape of the Boolean array needs to match the shape of the array you wish to conditionally sum.
J2:J8 is seven rows tall by one column wide.
The above formula creates an array of 1s and 0s from your three criteria ranges and shapes it into seven rows tall by one column wide.
At that point, SUMPRODUCT can do it's normal thing because the criteria array matches the dimension of the sum array J2:J8.

Mapping a 2D array into 1D array with variable column width

I know mapping 2D array into 1D array has been asked many times, but I did not find a solution that would fit a where the column count varies.
So I want get a 1-dimensional index from this 2-dimensional array
Col> _0____1____2__
Row 0 |_0__|_1__|_2__|
V 1 |_3__|_4__|
2 |_5__|_6__|_7__|
3 |_8__|_9__|
4 |_10_|_11_|_12_|
5 |_13_|_14_|
The normal formula index = row * columns + column does not work, since after the 2nd row the index is out of place.
What is the correct formula here?
EDIT:
The specific issue is that I have a list of items in with the layout like in the grid, but a one dimensional array for the data. So while looping through the elements in the UI, I need to get the correct data, but can only get the row and column for that element. I need to find a way to turn a row/column value into an index for the data-array
Bad picture trying to explain it
A truly optimal answer (or even a provably correct one) will depend on the language you are using and how it lays out memory for such arrays.
However, taking your question simply at face value, you have to know what the actual length of each row is in order to calculate a 1D index.
So either the row length follows some pattern that can be inferred from the data, or you have (or can write) a rlen = rowLength( 2dTable, RowNumber) function.
Then, depending on how big the tables are and how fast you need to run, you can calculate a 1D index from the 2d table by adding all the previous row lengths until the current row length is less than the 2d column index.
or build a 1d table of the row lengths (or commulative rowlengths) so you can scan it and so only call your rowlength function for each row only once.
With a better description of your problem, you might get a better answer...
For your example which alternates between 3 and 2 columns you can construct a formula:
index = (row / 2) * (3 + 2) + (row % 2 ? 3 : 0) + column
(C-like syntax, assuming integer division)
In general though, the one and only way to implement what you're doing here, jagged arrays, is to make an array of arrays, a.k.a. an Iliffe vector. That means, use the row number as index into an array of pointers which point to the individual row arrays containing the actual data.
You can have an additional 1D array having the length of the columns say "length". Then your formula is index=sum {length(i)}+column. i runs from 0 to row.

Excel: Fill a range of cells with a value or formula depending on only one cell

We have a project on a certain math subject and I am done with the computations and it works just fine. So the task is, let's say you have a system of linear equations of certain number of unknowns, you input the number of unknowns, and fill in the values, and using matrix computations, find all the value of unknowns.
To make this short, I already finished the "find the value of unknowns" along with the computation, I checked it, and it seems fine. I can put 6 as the number of unknowns and it automatically computes the inverse of a 6x6 matrix and it will return the 6 unknown values using Index INDIVIDUALLY.
(Note: We aren't allowed to use VBA or Macros since we haven't discussed that yet.
The problem is, I don't know how to automatically fill a RANGE of cells with a VALUE or A FORMULA based on a SINGLE cell value.
For example, In cell A1, I will input 5 (which indicates the number of unknowns), then upon inputting this and hitting enter, let's say a range of cells A2 to A6 (which is 5 cells) will be automatically filled with incremented letters, like for A2 -> A ; A3 -> B ; ... A6 -> E, of which these letters indicate the 5 unknowns.
PROBLEM 2.
Another follow up question, let's say I input again 5, which again stands for the number of missing values/unknowns, in A1, besides the column of the variables A,B,C,D,E (5 unknowns), I want to automatically fill column B respectively with values from an array.
This is just the same with my first problem but this time, instead of incremented letters, it would be Incremented Index function.
For example: I input 5
*Column A will automatically be filled with the variables/letters
*Column B will automatically be filled with the values from an array that's computed using a formula but is not shown independently on cells.
I already have the formula
INDEX(Formula I created, Row number of the answer from the Formula I created , Column number of the answer from the formula I created)
The answers from the formula I made myself is also an array, an "n" rows and 1 column array. If I put the Index formula on a SINGLE cell, it returns specified row number value from the array that resulted in the computation from my formula
What I want is for example, for 5 unknowns
**A | B**
1|.......5..........................
2|.......A..............Some Value 1
3|.......B..............Some Value 2
4|.......C..............Some Value 3
5|.......D..............Some Value 4
6|.......E..............Some Value 5
Wherein the "Some Value" is the Arrayed Answer from my formula and the "1,2,3,4,5" specifies the row number from that arrayed answer.
This is upon inputting the matrix values, inputting the number of unknowns "n" in A1, and automatically filling a range of cells A2 to A"n" with letters A up to what letter "n" corresponds, and automatically filling a range of Cells B2 to B"n" with my formula but with incremented row number for every row in the Index(Formula, Row number , Column number) function.
Note: I hope there's a way to do this using excel functions only since we haven't discussed VBA or Macros yet so we can't use those, and even If we can, I have no knowledge for that. haha. :D
THANK YOU THANK YOU THANK YOU SO MUCH IN ADVANCED! Cheers. :D
Here's a formula for column A:A (write this in cell A2) and drag down:
=IF(ROW()-1<=$A$1,CHAR(ROW()+63),"")

Sum along absolute values in an Array in Matlab

My array contains a string in the first row
how can I sum the array from the 2nd row to the Nth/1442th row (as in my example) disregarding the negative signs present in the column?
for example, my code for an array called data2 is:
S = sum(data2(2,15):data2(1442,15));
so sum all of the elements from row 2 to row 1442 in column 15.
This doesn't work but it also does not have anything to deal with the absolute value of whatever row its checking
data is from a .csv:
You should do something like this:
sum(abs(data(2:1442,15)));
The abs function will find the absolute value of each value in the array (i.e. disregard the negative sign). data(2:1442,15) will grab rows 2-1442 of the 15th column, as you wanted.
EDIT: apparently data is a cell array, so you could do the following, I think:
sum(abs([data{2:1442,15}]));
Ok so it looks like you have a constant column so
data2(2,15) = -0.02
and further down
data2(1442,15) = -0.02 %(I would assume)
So when you form:
data2(2,15):data2(1442,15)
this is essential like trying to create an array but of a single value since:
-0.02:-0.02
ans =
-0.0200
which of course gives:
>> sum(-0.02:-0.02)
ans =
-0.0200
What you want should be more like:
sum(data2(2:1442,15))
That way, the index: 2:1442, forms a vector of all the row references for you.
To disregard the negative values:
your answer = sum(abs(data2(2:1442,15)))
EDIT: For a cell array this works:
sum(abs(cell2mat(data2(2:1442,15))))

Resources