MATLAB: Write string into Excel - arrays

I am trying to write an array of coefficients into an Excel file under 1 column (A1). Here is my snippet:
filename = 'cheby2coefs.xlsx';
for Order = 1:1
fprintf('This is');
disp(Order);
[b,a] = cheby2(Order, 20, 300/500);
disp([b,a]);
%xlswrite(filename,{'Order ',Order},'A1'); %string
xlswrite(filename,'b','A1'); %string
xlswrite(filename,b');
xlswrite(filename,'a'); %string
xlswrite(filename,a');
end
The output that i aim for is something like this:
However, my code just keeps creating other sheets. What is the proper way to implement this?

The problem is in the xlswrite lines:
From xlswrite documentation:
xlswrite(filename,A,sheet) writes to the specified worksheet.
That means you are writing string 'b' to sheet 'A1' with xlswrite(filename,'b','A1');
xlswrite(filename,A) writes array A to the first worksheet in Excel
file, filename, starting at cell A1.
You actually do not need to do anything to start writing at A1. Assuming b is a row vector:
xlswrite(filename,b');
as you have written, should suffice.
If you want to specify sheet and column you can use
xlswrite(filename,A,sheet,xlRange)
Update: I cannot try this right now but I think it should work.
You can calculate a and b for every order and write them to an xls file like this:
r = 1; % row number
str = {'a', 'b'};
order = [1 3 5]; % The orders you want to calculate a and b with
for idx = 1:size(order, 2)
[b,a] = cheby2(order(idx), 20, 300/500); % I do not know about second
% and third parameters, you should
% check them.
vals = [a; b]; % assuming they are row vectors
cellName = strcat('A', r);
orderName = strcat('Order ', order(idx));
xlswrite(filename, orderName, 1, cellName)
r = r + 1;
for jdx=1:2
cellName = strcat('A', r);
xlswrite(filename, str{jdx}, 1, cellName);
r = r + 1;
cellName = strcat('A', r);
xlswrite(filename, vals(jdx, :), 1, cellName);
r = r + size(vals, 2);
end
end

xlswrite keeps creating new sheets with every call because you didn't specify the worksheet number.
Instead, try this:
%// Write b under column A1 in the 1st worksheet
xlswrite(filename, 'b', 1, 'A1')
xlswrite(filename, b(:), 1, 'A2')
It's good practice to make sure that b is written as a column by converting it to a column vector first with the b(:) syntax.
In addition, if you want to write the next set of coefficients under column B1, you can do the following:
%// Write a under column B1 in the 1st worksheet
xlswrite(filename, 'a', 1, 'B1')
xlswrite(filename, a(:), 1, 'B2')
Note that the passed sheet number remains 1.

Have you tried xlswrite1 ? You can download the module from here here
Here is the complete module :
filename = 'cheby2coefs.xlsx';
Excel = actxserver('Excel.Application');
Workbook = invoke(Excel.Workbooks, 'open', filename);
set(Excel,'Visible',1);
temp_text= [{'Text'}];
Location = ['A1:A1'];
sheetname = 'Sheet1';
%%
[status, message] = xlswrite1(ExcelFilename, temp_text, sheetname, Location);
if status == 0,
errordlg(message.message);
end
invoke(Workbook,'Save');
invoke(Excel,'Quit');
delete(Excel);
Hope it helps.

Related

How to transform 'double' into 'cell array'?

My code:
B = zeros(height(A),1);
col_names = A.Properties.VariableNames; % Replicate header names
for k = 1:height(A)
% the following 'cellfun' compares each column to the values in A.L{k},
% and returns a cell array of the result for each of them, then
% 'cell2mat' converts it to logical array, and 'any' combines the
% results for all elements in A.L{k} to one logical vector:
C = any(cell2mat(...
cellfun(#(x) strcmp(col_names,x),A.L{k},...
'UniformOutput', false).'),1);
% then a logical indexing is used to define the columns for summation:
B(k) = sum(A{k,C});
end
generates the following error message.
Error using cellfun
Input #2 expected to be a cell array, was double instead.
How do I solve this error?
This is how table 'A' looks like:
A.L{1,1} contains:
C = any(cell2mat(...
cellfun(#(x) strcmp(col_names,x),A.L{k},...
'UniformOutput', false).'),1);
here A.L{k} gets the contents of the cell located at the kth position of A.L. Using A.L(k) you get the cell itself which is located at A.L:
tmp = A.L(k);
C = any(cell2mat(...
cellfun(#(x) strcmp(col_names,x),tmp{1},...
'UniformOutput', false).'),1);
Bit of a hacky way, as you first need to get the cell at A.L(k) and then need the contents of that cell, so you need a temporary variable.
I'm not entirely sure quite what's going on here, but here's a fabricated example that I think is similar to what you're trying to achieve.
%% Setup - fabricate some data
colNames = {'xx', 'yy', 'zz', 'qq'};
h = 20;
% It looks like 'L' contains something related to the column names
% so I'm going to build something like that.
L = repmat(colNames, h, 1);
% Empty some rows out completely
L(rand(h,1) > 0.7, :) = {''};
% Empty some other cells out at random
L(rand(numel(L), 1) > 0.8) = {''};
A = table(L, rand(h,1), rand(h, 1), rand(h, 1), rand(h, 1), ...
'VariableNames', ['L', colNames]);
%% Attempt to process each row
varNames = A.Properties.VariableNames;
B = zeros(height(A), 1);
for k = 1:height(A)
% I think this is what's required - work out which columns are
% named in "A.L(k,:)". This can be done simply by using ISMEMBER
% on the row of A.L.
C = ismember(varNames, A.L(k,:));
B(k) = sum(A{k, C});
end
If I'm completely off-course here, then perhaps you could give us an executable example.

Finding same value in rows & columns of a 2D array

Hi guys I want to solve sodoku puzzles in matlab. My problem is that I should find same value in every row and every column and every 3*3 sub array.
Our 2d array is 9*9 and populated with value 1-9 randomly.
I wrote this for finding same value in rows, but I don't know how I should do it for columns and 3*3 sub arrays.
conflict_row = 0;
for i=1:9
temp = 0;
for j=1:9
if (temp==A(i,j))
conflict_row = conflict_row+1;
end
temp = A(i,j);
end
end
Sorry I'm a newbie.
Find values that are present in all columns:
v = find(all(any(bsxfun(#eq, A, permute(1:size(A,1), [3 1 2])),1),2));
Find values that are present in all rows:
v = find(all(any(bsxfun(#eq, A, permute(1:size(A,2), [3 1 2])),2),1));
Find values that are present in all 3x3 blocks: reshape the matrix as in this answer by A. Donda to transform each block into a 3D-slice; then reshape each block into a column; and apply 1:
m = 3; %// columns per block
n = 3; %// rows per block
B = permute(reshape(permute(reshape(A, size(A, 1), n, []), [2 1 3]), n, m, []), [2 1 3]);
B = reshape(B,m*n,[]);
v = find(all(any(bsxfun(#eq, B, permute(1:size(B,1), [3 1 2])),1),2));
Probably not the fastest solution but why don't you make a function of it and use it once for rows and once for columns
[conflict_row ] = get_conflict(A)
for i=1:9
temp = 0;
for j=1:9
if (temp==A(i,j))
conflict_row = conflict_row+1;
end
temp = A(i,j);
end
end
And then you call it twice
conflict_row = get_conflict(A); % Rows
Transpose A to get the columns
Convert the columns to rows and use the same code as before
conflict_col = get_conflict(A.');
If you want to work within the same column then you should do something like this (also sorry this is in C# I don't know what language you are working in):
int currentCol = 0;
foreach (var item in myMultiArray)
{
int currentColValue = item[currentCol];
}
This works because myArray is a array of arrays thus to select a specific column can easily be picked out by just allowing the foreach to perform your row iteration, and you just have to select the column you need with the currentCol value.

How to convert a character matrix into cell array?

I have 64 characters in a 4*4 matrix.I need to convert it into a cell array such that cell has 4 characters.For eg
Consider A=[TCTGCTCTCGGTTATATACACTGCCCAGAACACGTCAACAAGGCCAGTGTATCCTTCTTTGTGT]
i need to get a cell array as below
B={[TCTG][CTCT][CGGT][TATA]
[TACA][CTGC][CCAG][AACA]
[CGTC][AACA][AGGC][CAGT]
[GTAT][CCTT][CTTT][GTGT]}
i tried using the mat2cell function but im not able to understand it.please help.
Using a for-loop:
clc
clear
A = 'TCTGCTCTCGGTTATATACACTGCCCAGAACACGTCAACAAGGCCAGTGTATCCTTCTTTGTGT';
B = cell(4,4);
currentIdx = 0; % Use index to increment by steps of 4 when going through A
for k = 1:16
B{k} = A(currentIdx+1:currentIdx+4);
currentIdx = currentIdx+4;
end
B = B'
B =
'TCTG' 'CTCT' 'CGGT' 'TATA'
'TACA' 'CTGC' 'CCAG' 'AACA'
'CGTC' 'AACA' 'AGGC' 'CAGT'
'GTAT' 'CCTT' 'CTTT' 'GTGT'
You are starting with a 1xN matrix and want to convert it to a 1xN/4 cell array of 1x4 matrices. Your command should then be:
N = length(A);
M = 4;
B = mat2cell(A,1,ones(1,N/M)*M);
The first dimension is the 1, the second dimension is a string of 4's the size of the output cell array. The result:
B =
Columns 1 through 12
'TCTG' 'CTCT' 'CGGT' 'TATA' 'TACA' 'CTGC' 'CCAG' 'AACA' 'CGTC' 'AACA' 'AGGC' 'CAGT'
Columns 13 through 16
'GTAT' 'CCTT' 'CTTT' 'GTGT'
You can use method vec2mat that breaks your input vector to matrix
M = vec2mat(A, numberOfColumns)
(In your case numberOfColumns would be 16) and then use mat2cell. In your case, it would be:
C = mat2cell(M, [1,1,1,1], [4,4,4,4])
It means that all cels will have one row and 4 columns).
Effect of function c = mat2cell(x, [10, 20, 30], [25, 25]) would be:
The image shows why you have to convert vector to matrix. (example from matlab documentation)
You can also (ab)use the very versatile accumarray for this task:
A = 'TCTGCTCTCGGTTATATACACTGCCCAGAACACGTCAACAAGGCCAGTGTATCCTTCTTTGTGT';
n = 4;
B = accumarray(ceil(1/n:1/n:numel(A)/n).', A(:), [], #(x) {x.'}).'

Matrix Math with VBA (System of Linear Equations)

I'm looking for a little help performing some matrix mathematics in Excel's VBA. I've read a ton of replies that suggest using the Excel worksheet but I'm hoping to solve this within the VBA code itself.
Although my application is much larger, let's say I have a system of linear equations that I need to solve:
x1 + x2 = 8
2*x1 + 4*x2 = 100
This can be solved with the simple matrix formula A*x = B or x = A^(-1) * B where,
A = [1, 1; 2, 4]
B = [8; 100]
If you solve this, you'll find x1 = -34 and x2 = 42. In terms of the matrix, then:
X = [-34; 42]
Using Excel's worksheets alongside its MMULT and MINVERSE functions makes this easy and I've gotten it to work just fine. My problem is I'm needing to do this calculation inside a VBA function. Here's what I'm trying:
Dim A(0 To 1, 0 To 1) As Single
Dim B(0 To 0, 0 To 1) As Single
Dim X(0 To 0, 0 To 1) As Single
A(0, 0) = 1
A(1, 0) = 1
A(0, 1) = 2
A(1, 1) = 4
B(0, 0) = 8
B(0, 1) = 100
X = Application.WorksheetFunction.MMult(Application.WorksheetFunction.MInverse(A), B)
Unfortunately, the last line yields a "Compile error: can't assign to array" message. I think it's because I have to specify each element of the array one at a time, but the worksheet functions are array functions.
How do I fix this?
Two things:
The same rule applies as in actual mathematics: B must be a vertical array for matrix multiplication to be possible in your case. Declare it as
Dim B(0 To 1, 0 To 0) As Single
and initialize it accordingly. Also, just declare
Dim X As Variant
since the MMult returns a Variant array. This is what was causing your original error.

Google Script - how to replace cell values in Sheet 1 by searching Sheet 2 for those values and returning correlating data from another Sheet 2 column

Google Spreadsheet / Scripting Question:
Disclaimer: I am a beginner. Any explanation helps me tremendously.
Long story short:
Worksheet 1, Column N contains comma-separated values.
Worksheet 2, Column A has all possible values that could be combined to make up the content of Worksheet 1, Column N.
Worksheet 2, Column C contains "alternative" values.
I need a script that can replace all values in Worksheet 1, Column N with the "alternative" values from Worksheet 2, Column C. I need the final result to be the "alternative" values in a single, comma-separated value.
I have already scripted to separate Column N values into individual values in new columns. However, I have not been able to advance further. My current splitting script appears at the bottom.
Full explanation:
"Worksheet 1" contains multiple columns, including Column "N" that contains comma-separated values. The number of rows in Sheet 1 will grow as users enter data. Currently, there are only three rows of data. Column "N" contains:
N1 has a value of "Dog, Cat, Rabbit"
N2 has a value of "Dog, Fish"
N3 has a value of "Frog, Horse, Fish"
My current Google Script gathers data from all available rows, and it then separates the comma-separated values in Column "N" into new columns, like so:
X1 has a value of "Dog", Y1 has a value of "Cat", and Z1 has a value "Rabbit"
X2 has a value of "Dog", Y2 has a value of "Fish"
X3 has a value of "Frog", Y3 has a value of "Horse", and Z3 has a value of "Fish"
"Worksheet 2" contains, in column A, all possible values that might appear above -- Dog, Cat, Rabbit, Fish, Horse, etc. So,
A1 has a value of "Dog"
A2 has a value of "Cat"
A3 has a value of "Rabbit"
A4 has a value of "Fish" -- etc. (there are 100+ total possible values).
"Worksheet 2" contains, in column C, "alternative values" (i.e., corresponding Google Calendar Resource Addresses):
C1 has a value of "domain.com_928313sdf98#resource.calendar.google.com"
C2 has a value of "domain.com_190382d0931#resource.calendar.google.com"
C3 has a value of "domain.com_295801a0181#resource.calendar.google.com"
C4 has a value of "domain.com_5s3910s1481#resource.calendar.google.com" --- etc.
I am seeking a script that, for the data in Worksheet 1, would search for the separated values in Worksheet 2 and then replace those values in Worksheet 1 with the correlating "alternative values" (i.e., Google Calendar Resource Addresses) from Worksheet 2, Column C. I then need it to concatenante the results back into a comma-separated value.
So, I want to start with Worksheet 1, where N1 has a value of "Dog, Cat, Rabbit," and I want to get back "domain.com_928313sdf98#resource.calendar.google.com, domain.com_190382d0931#resource.calendar.google.com, domain.com_295801a0181#resource.calendar.google.com" as my final result. The script would perform this across all rows.
My Splitting Script (I am not even sure if this is the best way of handling this):
function mySplit() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var startcolumn = 2;
var startrow = 2;
var numcolumns = 500;
var dataRange = sh.getRange(startcolumn, 1, numcolumns, 25);
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var cell = sh.getRange(startcolumn + i, 15).getValues()[0];
var sCell = cell[0].split(",");
sh.getRange(startrow +i,26,1,sCell.length).setValues([sCell]);
}}
As I already mentioned in your other post, this is quite simple to do with arrays, here is a working example with your new data: see sheet here (read only, make a copy to test)
function replaceTagsWithRessource(){ // in this example sheet, the function will replace aa with 11, bb with 22 etc...
var sh1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet1');
var sh2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet2');
var sourceCol = sh1.getRange('N2:N').getValues();
Logger.log(sourceCol)
var targetRef = sh2.getDataRange().getValues();
Logger.log(targetRef)
var newColN = []
for(var s in sourceCol){
var caltoUse = sourceCol[s][0].split(',');
var calID = []
for(var n in caltoUse){
for(var r in targetRef){
if(caltoUse[n]==targetRef[r][0]){ calID.push(targetRef[r][2])} // get the cal ref in col 3
}
}
newColN.push([calID.toString()]);
Logger.log(newColN)
}
sh1.getRange('N2:N').setValues(newColN);// replace original values with new values (comma separated calendar IDs)
}

Resources