ode45 outputs are all NaN - matlab

I'm trying to solve this simple ODE system:
dydpdt = 1*(-f{2}-f{1}*dydp);
Stored in a function called funsensitivity (f is a cell array, with a 765x765 sparse matrix and a 765x1 vector, downloadable as a .MAT file here ). I call it using:
dydp0 = zeros(size(f{2}));
[t2,JJ]=ode45(#(t,y)funsensitivity(t,y,f),0:4000:100000,dydp0);
JJ is the right size, I get no errors, but all values in JJ are NaN. I have no idea why this could happen. What am I doing wrong?

You are using {} to index, which is for cell arrays. You should be using ():
dydpdt = 1*(-f(2)-f(1)*dydp);
and also
dydp0 = zeros(size(f(2)));
[t2,JJ]=ode45(#(t,y)funsensitivity(t,y,f),0:tstep:tfinal,dydp0);
EDIT based on comments:
I have tried running your code in Octave (don't have MATLAB), and it looks like your problem is unstable by looking at the solution:
JJ =
Columns 1 through 10:
0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000
5.1645e+001 1.0181e+004 1.2727e+003 -1.1492e+004 -1.2900e+001 -7.2862e+001 7.2502e+001 7.7228e-003 1.1269e-002 1.4324e-003
1.5631e+031 1.3173e+033 1.6466e+032 -1.4936e+033 -3.7860e+030 -2.2204e+031 2.2012e+031 7.4674e+026 1.0897e+027 1.3851e+026
7.0857e+060 3.7159e+062 4.6449e+061 -4.2334e+062 -1.6685e+060 -1.0125e+061 1.0005e+061 1.9564e+056 2.8548e+056 3.6287e+055
3.4854e+090 1.3800e+092 1.7250e+091 -1.5787e+092 -7.9162e+089 -5.0174e+090 4.9378e+090 7.0373e+085 1.0269e+086 1.3053e+085
-5.3460e+120 5.8857e+121 7.3572e+120 -6.2253e+121 1.3755e+120 7.4917e+120 -7.4825e+120 3.1352e+115 4.5748e+115 5.8151e+114
-2.3670e+152 2.7260e+151 3.4075e+150 1.4565e+152 5.7833e+151 3.3559e+152 -3.3303e+152 9.3359e+145 1.3623e+146 1.7316e+145
-7.6120e+183 1.3332e+181 1.6682e+180 5.6622e+183 1.8358e+183 1.0823e+184 -1.0724e+184 3.3770e+177 4.9277e+177 6.2636e+176
-2.4360e+215 6.7970e+210 9.2304e+209 1.8189e+215 5.8022e+214 3.4726e+215 -3.4359e+215 1.4223e+209 2.0755e+209 2.6381e+208
-7.7953e+246 4.4692e+240 3.6568e+240 5.8278e+246 1.8337e+246 1.1142e+247 -1.1008e+247 6.0021e+240 8.7582e+240 1.1133e+240
-2.4947e+278 4.0992e+271 1.3587e+272 1.8673e+278 5.7955e+277 3.5749e+278 -3.5270e+278 2.5328e+272 3.6959e+272 4.6979e+271
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
You might want to try a stiff solver such as ode15s to see if it improves things, or using a smaller time step in your time vector, but it looks like the problem is fundamentally wrong (numerically at least).

Related

How to get utility Matrix from initial dataset?

While I apply Alternating Least Squares,I found need to use utility matrix.
I'm working on 20 milion Movielens dataset which contain rating file(userId ,MovieId ,Rating).
I know utility matrix (M X N) where M is the number of users and N is the number of Movies .
my question: How to build utility matrix from rating file?
As, the 20M dataset couldn't fit in my computer, during the pivot call, I am showing the process for 1M dataset.
import re
import os
import zipfile
import numpy as np
import pandas as pd
from sklearn import preprocessing
from urllib.request import urlretrieve
# Creating required folders, if they don't exist
def create_dir(dirname):
if os.path.exists(dirname):
print(f"Directory {dirname} already exists.")
else:
os.mkdir(dirname)
create_dir('Datasets')
print("Downloading movielens data...")
urlretrieve("http://files.grouplens.org/datasets/movielens/ml-1m.zip", "movielens.zip")
zip_ref = zipfile.ZipFile('movielens.zip', "r")
zip_ref.extractall()
print("Extraction done")
# Loading ratings dataset and renamed extracted folder
ratings = pd.read_csv('ml-1m/ratings.dat', sep='::', names=['userId', 'movieId', 'rating', 'timestamp'])
ratings = ratings.drop(columns=['timestamp'])
ratings.to_csv('Datasets/ratings.csv', index=False)
print(ratings.shape)
pivot_table = ratings.pivot_table(index=['userId'], columns=['movieId'], values='rating')
pivot_table.to_csv('Datasets/user_vs_movies.csv', index=False)
pivot_table.head()
Output:
Downloading movielens data...
Extraction done
(1000209, 3)
movieId 1 2 3 4 5 6 7 8 9 10 ... 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952
userId
1 5.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN 2.0 NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 rows × 3706 columns

reshaped elements in different positions relative to original array - matlab [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
a=randn(4,4,2,3)
a(:,:,1,1) =
0.5377 0.3188 3.5784 0.7254
1.8339 -1.3077 2.7694 -0.0631
-2.2588 -0.4336 -1.3499 0.7147
0.8622 0.3426 3.0349 -0.2050
a(:,:,2,1) =
-0.1241 0.6715 0.4889 0.2939
1.4897 -1.2075 1.0347 -0.7873
1.4090 0.7172 0.7269 0.8884
1.4172 1.6302 -0.3034 -1.1471
a(:,:,1,2) =
-1.0689 0.3252 -0.1022 -0.8649
-0.8095 -0.7549 -0.2414 -0.0301
-2.9443 1.3703 0.3192 -0.1649
1.4384 -1.7115 0.3129 0.6277
a(:,:,2,2) =
1.0933 -1.2141 -0.7697 -1.0891
1.1093 -1.1135 0.3714 0.0326
-0.8637 -0.0068 -0.2256 0.5525
0.0774 1.5326 1.1174 1.1006
a(:,:,1,3) =
1.5442 -1.0616 -0.1924 -1.4224
0.0859 2.3505 0.8886 0.4882
-1.4916 -0.6156 -0.7648 -0.1774
-0.7423 0.7481 -1.4023 -0.1961
a(:,:,2,3) =
1.4193 -0.8045 0.2157 0.7223
0.2916 0.6966 -1.1658 2.5855
0.1978 0.8351 -1.1480 -0.6669
1.5877 -0.2437 0.1049 0.1873
[d1 d2 d3 d4]=size(a);
aa=reshape(a,[],d4)';
b(:,:,1)=[0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0]
b(:,:,2)=[0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0]
bb=reshape(b,1,[]);
aa(:,find(~bb))=NaN;
c=reshape(aa,d1,d2,d3,d4);
c(:,:,1,1) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,1) =
NaN NaN 3.5784 NaN
NaN NaN -0.1022 NaN
NaN NaN -0.1924 NaN
NaN NaN NaN NaN
c(:,:,1,2) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,2) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,1,3) =
NaN NaN 0.4889 NaN
NaN NaN -0.7697 NaN
NaN NaN 0.2157 NaN
NaN NaN NaN NaN
c(:,:,2,3) =
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
Why are the nonnan elements in c in a different position relative to their position in the original array a?
I was expecting the output
c(:,:,1,1) =
NaN NaN 3.5784 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,1) =
NaN NaN 0.4889 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,1,2) =
NaN NaN -0.1022 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,2) =
NaN NaN -0.7697 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,1,3) =
NaN NaN -0.1924 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
c(:,:,2,3) =
NaN NaN 0.2157 NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
When I make these changes to your code, the output matches your expected output:
a = randn(4,4,2,3);
[d1 d2 d3 d4] = size(a);
aa = reshape(a,[],d4); % <-- NOTE! no transpose
b = [0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0];
b(:,:,2) = [0 0 1 0;0 0 0 0; 0 0 0 0 ;0 0 0 0];
bb = reshape(b,1,[]);
aa(find(~bb),:) = NaN; % <-- NOTE! swapped indexing
c = reshape(aa,d1,d2,d3,d4);
By transposing the array aa, and not transposing back later, all elements ended up in a different location.
Edit: #Sardar Usama makes a good point in the comment below. You can accomplish the same thing like this:
c = a;
c(repmat(~b,[1,1,1,3])) = NaN
(and probably on other ways too, e.g. he's suggesting multiplication which would accomplish the same thing.)

How to create a table with NaNs in Matlab?

I am trying to create a table that is 10 x 5 with only NaNs. I start by creating an array with NaNs:
N = NaN(10, 5);
then I try converting it to a table:
T = table(N);
It puts all cells into one column, but I need the table to be 5 columns with one NaN in each cell. Does anyone know how to do that?
array2table
works just fine. This takes a matrix and converts it to the table structure where each column of the matrix is a column in the output table:
>> N = NaN(10, 5);
>> T = array2table(N)
T =
N1 N2 N3 N4 N5
___ ___ ___ ___ ___
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN
What you want is:
t = array2table(NaN(10,5))
Bonus (so our answers are slightly different :P) You can rename the variables to anything you want with something like:
t.Properties.VariableNames = {'x1','x2','x3','x4','x5'};

Matlab contourf plots interpolation

Hi If I have data like this e.g.
x=[1:1:7];
y=[5:-1:1]';
z=[NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN
0.955113030084974 0.948571658876062 0.942624899410361 NaN NaN NaN NaN
0.937493758208870 0.928392864395896 0.920119550965773 0.910466888808695 0.901586502842837 0.892741292179595 NaN
0.879644551679863 0.862126561405869 0.846200299426160 0.827622958701087 0.810531605135333 0.793507569055583 0.775604152867929
];
I'd like to generate a contourf (i.e. contourf(x,y,z);) plot that gets rid of the steps i.e. the result should be a smooth curve at the border.
You could use imagesc instead, but the reason that there are such harsh steps is that you don't have enough data points. To change that, one option is to interpolate more data points in between what you have.
x=[1:1:7];
y=[5:-1:1]';
z=[NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN
0.955113030084974 0.948571658876062 0.942624899410361 NaN NaN NaN NaN
0.937493758208870 0.928392864395896 0.920119550965773 0.910466888808695 0.901586502842837 0.892741292179595 NaN
0.879644551679863 0.862126561405869 0.846200299426160 0.827622958701087 0.810531605135333 0.793507569055583 0.775604152867929];
xn = 1:.01:7;
yn = [5:-.01:1]';
zn = interp2(x,y,z,xn,yn);
imagesc(xn,yn,zn);

How to extract valid value from a sparse vector in Matlab?

I have lots of vectors like this one below, very sparse, lots of 'NaN'. What I intend to do is to extract the valid number out of this vector, and put them into a separate vector with no 'NaN' values.
And every vector has different positions with valid number, so I can't put them into a matrix then extract rows.
Thus please help me with this!
10459865
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
8751943
NaN
NaN
NaN
NaN
NaN
NaN
6951680
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
5991217
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
5327653
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
4740048
NaN
NaN
4265221
NaN
NaN
3973280
Assuming that vector is stored in variable a,
a(isfinite(a))
will extract just the valid (finite) entries.
You can use the isnan() function to find out if an entry is a number. Then something like
x = vector of values;
new_x = x(~isnan(x));
new_x is a vector with only the valid numbers.