Importing Data into Simulink Block Diagrams Issue - arrays

To all MATLAB and Simulink users,
I am doing a project and faced a problem importing data from a 'Signal From Workspace' in Simulink block.
My case:
I need to input 565 rows of 2 columns of data over a sample period of 22seconds into my Simulink block diagram. Each data sample time is 22/565.
However, the output data is a [565 x 2] which affects the input to the downstream Simulink blocks due to dimensions issue.
For example, Ideally, [1 x 2] output multiplies with [2 x 1] and repeat for 565 times over 22 seconds. Now, [565 x 2] output signal couldn't get through due to the dimension.
My attempts to solve the problem:
I tried using 'From workspace' instead of 'Signal From Workspace' but face some problems.
t=[0:22/565:22]' M (565 rows n 2 columns of values) data.time=t; data.signals.values = M; data.signals.dimensions=[565 2];
This error pops up when simulation is run:
*"Invalid structure-format variable specified as workspace input in 'test/From Workspace'. The structure 'dimensions'field must be a scalar or a vector with 2 elements. In addition, this field must be compatible with the dimensions of input signal stored in the 'values' field. " *
I greatly appreciate if anybody can provide insight/solutions/alternative method to my case.
THANK YOU!
Regards,
KO

It looks like you should be using
data.signals.dimensions = 2;
For example
>> t= linspace(0,10,1001)';
>> data.time = t;
>> data.signals.values = [sin(t) cos(t)];
>> data.signals.dimensions = 2;

Related

Is there any mechanism to auto squeeze in Matlab / Octave

For an nD array, it would be nice to be able to auto squeeze to remove singleton dimensions. Is there a way to do this that I don't know about? This would be especially useful for aggregate functions (e.g. sum, mean, etc) where you always expect a result with fewer dimensions.
Here's a simple example:
>> A = ones(3,3,3);
>> B = mean(A);
>> size(B)
ans =
1 3 3
>> squeeze(B)
ans =
1 1 1
1 1 1
1 1 1
It would be nice if Matlab/Octave would automatically do the squeezing for me. Or if there was a way to turn that option on (something similar to hold on for plots).
As far as I know, Matlab does not have that. And I don't think it would be a good idea. Consider a modified version of your example:
>> A = ones(3,1,1,3);
>> B = mean(A);
>> size(B)
ans =
1 1 1 3
What should "auto-squeeze" do here? Reduce B to size [1 1 3] or to [1 3]?
You could argue that it should remove the same dimension that mean has turned into a singleton. But then it would have to be done within the mean function, perhaps with an optional input argument. Once you get the function output, there is no information how it was obtained.
Or you could argue that it should remove all singleton dimensions, like squeeze (more or less) does. But then it would remove dimensions that were already singleton in the function input, which is probably unwanted.
If you ask me, having a second input in squeeze specifiyng which (singleton) dimensions to remove would be a nice addition (in the same vein as you can use mean(A, 1) to force the operation to be applied along the first dimension even if A happens to be a row vector).
I agree with Luis and Cris, but I would add the following.
Both Matlab and Octave do automatically squeeze extra dimensions, in a very particular scenario: any dimensions at the end that have been reduced to singletons, are automatically squeezed out.
E.g.
A = ones([1,2,3,4]);
B = mean(A, 4);
size(B)
% ans = 1 2 3
Note, how the answer is [1,2,3], and not [1,2,3,1]. This is in contrast to languages like python, for instance, where a size of (1,1) is very different to a size of (1,).
Therefore, with regard to your questions, one way to use this to your advantage could be to ensure that the dimension that is to be reduced is always found at the end, and thus automatically simplified.
This becomes even more useful when you realise that:
size(A(:)) % ans = 24 1 (i.e. 24)
size(A(:,:)) % ans = 1 24
size(A(:,:,:)) % ans = 1 2 12
size(A(:,:,:,:)) % ans = 1 2 3 4
Meaning, if you order your dimensions hierarchically you can ensure that any operations that need to take place over the higher dimensions, can a) be vectorised easily, and b) give a natural result, without the need to waste time squeezing or permuting the resulting dimensions.

Logistic Regression and Sparse matrices -AttributeError: 'bool' object has no attribute 'any'

I am trying to use logistic regression with sparse matrices, because it may work faster. Problem is, I get errors and warnings that I do not understand. I will show you some code. I warn you, I am new to this, so if you can pinpoint any unnecessary-bad code of me, please say so.
My logic is the following: (I will present code as well if written text does not help at all)
1) Train_set and test_set all at one set to perform the preprocessing at once (fill gaps, onehotencdoing etc) and to transform everything in sparse form
2) Then, after preprocessing, I need to slice this set into the 2 sets, one for train (to make the model) and the test (which I want to predict)
3) To slice though, I transform from coo to csr, otherwise I cannot do it.
4) After I sliced, I do the usual for modelling and then problems occur.
Time to show some code:
# read csv
train_set = pd.read_csv('train.csv', sep=',', nrows=10000, keep_default_na=True)
test_set = pd.read_csv('test.csv', sep=',', nrows=10000, keep_default_na=True)
#all_set includes both train & read data
all_set = pd.concat([train_set, test_set], sort=False)
# Pass values of train_set to X
X = all_set[all_set.columns]
X = X.drop(['id', 'target'], axis=1)
# Pass target values to Y and convert it to a sparse matrix
Y = train_set['target']
Y = sparse.csr_matrix(Y)
Y = csr_matrix.transpose(Y)
(after preprocessing)
# Seperate data into Train and Test with preprocessing complete
# first I transform coo to csr (fro new_Train) because for coo slicing is unavailable
csr_Train = new_Train.tocsr()
final_train_set = csr_Train[0:len(train_set['target']), :]
final_test_set = csr_Train[len(train_set['target']):all_set.shape[0], :]
Y contains my target column to use for training and
final_train_set is my train data
print("shape and type", final_train_set.shape, type(final_train_set))
print("shape and type", Y.shape, type(Y))
Results: (edit: Even if both were coo or both were csr, I got the same errors and warnings)
Seeing the same shape and all, all optimistic I proceed to modelling.
X_train, X_test, y_train, y_test = train_test_split(final_train_set, Y, random_state=42, test_size=0.2)
lr = LogisticRegression(solver='lbfgs')
lr.fit(X_train, y_train)
The shape and type are the same. And here are the results...
C:\Users\kosta\Anaconda3\lib\site-packages\sklearn\utils\validation.py:724: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
y = column_or_1d(y, warn=True)
C:\Users\kosta\Anaconda3\lib\site-packages\sklearn\utils\fixes.py:192: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
return X != X
C:\Users\kosta\Anaconda3\lib\site-packages\sklearn\utils\fixes.py:192: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
return X != X
Traceback (most recent call last):
File "C:/Users/kosta/PycharmProjects/cat_dat/Cat_Dat_v2.py", line 110, in <module>
lr.fit(X_train, y_train)
File "C:\Users\kosta\Anaconda3\lib\site-packages\sklearn\linear_model\logistic.py", line 1532, in fit
accept_large_sparse=solver != 'liblinear')
File "C:\Users\kosta\Anaconda3\lib\site-packages\sklearn\utils\validation.py", line 725, in check_X_y
_assert_all_finite(y)
File "C:\Users\kosta\Anaconda3\lib\site-packages\sklearn\utils\validation.py", line 59, in _assert_all_finite
if _object_dtype_isnan(X).any():
AttributeError: 'bool' object has no attribute 'any'
Process finished with exit code 1
To be honest, I don't understand what's wrong (neither the warnings nor the errors) and I don't know how to proceed, apart from many trials and researching on net that I did for hours. So any help will do!
Thank you in advance for your time!
It seems the problem was with the target column. I should have not converted it at sparse form. I should have left it as a pandasSeries. It seems that for model to work, the 2 arguments don't need to be of the same type.

Create an array 1*3 containing only one 1 and rest 0

I am just learning matlab now. I faced a difficulty in creating an array of 3 elements in a row.
I wrote a code
Source = randi ([0,1],1,3);
which gave me output
[1,1,0].....
[0,1,1]....
but I was willing to get only one 1 and two zeros in the output instead of getting two 1 and one zero.
I know I am wrong because I am using randi function and gives random value of 0 & 1 and output I get can be [0,0,1] ... [1,0,0]... too.
My clear problem is to only get only one 1 if I repeat as many times. e.g. I should get only [0,0,1] or [0,1,0] or [1,0,0].
Hope I can get solution.
Thank you.
Ujwal
Here's a way using randperm:
n = 3; %// total number of elements
m = 1; %// number of ones
x = [ones(1,m) zeros(1,n-m)];
x = x(randperm(numel(x)));
Here is a couple of alternative solutions for your problem.
Create zero-filled matrix and set random element to one:
x = zeros(1, 3);
x(randi(3)) = 1;
Create 1x3 eye matrix and randomly circshift it:
x = circshift(eye(1,3), [0, randi(3)]);

Store formulas as an element of an array in Matlab

(* I don't know programming in Matlab. It is just a general question about Matlab language. *)
In Excel, we can store a formula in a cell. For instance, if A2 contains a formula = A1+10, the re-evaluation of A2 returns 30 when the value of A1 is 20.
My question is, is there a similar mechanism in matlab? That said, can we specify a formula in a element of an array in Matlab, so that we can re-evaluate the array later?
Edit 1:
Following the comment of #rayryeng I try to make an example to illustrate the concept... Actually, this is exactly what spreadsheet languages such as Excel can do.
So my question is, is there a mechanism that permits the following in Matlab? (Note that the following syntax is just symbolic)
>> B = [1 2; B{1,1}+2 4] // store some values and a formula in the array
B =
1 2
3 4
>> B{1,1} = 10 // change the value of one cell
B =
10 2
3 4
>> EVAL(B) // there is a re-evaluation command to re-calculate all the cells
ans =
10 2
13 4
Hopefully I'm understanding what you want correctly, but the answer is indeed yes. You can store "formulas" in a cell array where each element is a handle or an anonymous function.
Perhaps you mean something like this:
formulae = {#(x) x+10, #sin, #cos, #(x) x / 3};
The syntax # denotes a function handle and the (x) denote that this is an anonymous function with the input variable x. The first cell element provides a function that adds 10 to every value that goes into it, the second and third parameters are handles to sin and cos, so these act like those trigonometric functions. The last handle divides every value that goes into it by 3.
To demonstrate, let's create a small array, then go through each formula and apply each of them to the small array:
>> formulae = {#(x) x+10, #sin, #cos, #(x) x / 3};
>> A = [1 2; 3 4]
A =
1 2
3 4
>> formulae{1}(A)
ans =
11 12
13 14
>> formulae{2}(A)
ans =
0.8415 0.9093
0.1411 -0.7568
>> formulae{3}(A)
ans =
0.5403 -0.4161
-0.9900 -0.6536
>> formulae{4}(A)
ans =
0.3333 0.6667
1.0000 1.3333
We first create the formulae, then create a small 2 x 2 matrix of [1 2; 3 4]. After, we access each formula's cell, then put in the input A into the function and we get what you see.
However, when you're starting out, start with actually declaring functions in function scripts.... don't use this kind of style of programming for practical applications. It makes your code less readable. For example, doing sin(A) is much more readable than formula{2}(A). People reading your code have to remember what position in the array corresponds to what formula you are applying to each element in the input.

MATLAB - How to append to matrix rows using a forloop

Im semi-new with matlab, i've been using it in my course for a while now, but never really been taken in by it.
I have a vector of quite a large size, it is a sound file to be accurate. I'm required to take every 128 elements from this vector, and add them to a matrix.
So matrix row 1 will contain the first 128 (1-128) elements, matrix row 2 will contain the second 128 (128-256) etc...
How can I go about doing this? I've looked up the matlab mathworks help files and havent been able to find anything. I know I can append matrices using z = [x,y] but its not working for me...
Appreciate any help, thanks!
You can do this with the reshape command:
>> A = [1 2 3 4 5 6];
>> B = reshape(A, 3, 2)'
B =
1 2 3
4 5 6
Look at the reshape command. If you start with a (N*128 by 1) vector then with reshape(A,[N,128]) you should get a (N by 128) matrix.
As others said reshape command is the right tool for you. But before you start using reshape, you would like to make sure two things:
usually for any sound file there will be some header information, you need to start reading from the file position after the header information. you can find online manuals to get the size of header-data, for example the canonical sound data format can be found here: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
If the format of your sound file is something else then you'll have to find it out.
the number of samples to be read should be either truncated or padded to multiple of 128 since you want a matrix of N*128 size
This can be done slightly more conveniently even, as reshape can compute one of its argument itself
In MarkD's answer:
A = [1 2 3 4 5 6];
B = reshape(A, 3, 2)'
replace the second line with
B = reshape(A, 3, [])'
The [] input tells reshape: determine yourself what this should be (length(A)/3 in your case)

Resources