How do I find the average slope of a 3-D surface? MatLab - matlab

`2.4 2.34 2.21 1.90 1.4 0.83 0
2.34 2.42 2.16 1.79 1.3 0.7 0
2.21 2.16 1.99 1.64 1.16 0.51 0
1.90 1.79 1.64 1.30 0.75 0 0
1.4 1.34 1.16 0.75 0 0 0
0.83 0.75 0.51 0 0 0 0
0 0 0 0 0 0 0
`
This is what my matrix looks like at one point in time and Id like to calculate the average slope or gradient of the surface( An indicator of steepness).
It seems like MatLab should have a built in function for this sort of thing but I can find one. I have also tried a code that I wrote but it is not accurate.
Best,
Abid

the gradient is vectorial, so you can treat the two dimensions separately.
Calculating the gradient consists of calculating the first derivative to every parameter of the function. In the discrete domain, this can be done by taking the finite differences: http://en.wikipedia.org/wiki/Finite_difference
If you want it exact and calculate the gradient at each point, you can't just take the forward or backward differences, because at the edge, you don't always have a forward (or backward) point.
But I think if you just want the mean of the gradient, you don't have to bother with the edges and you can just compute the finite differences for the central points between your original points by using diff:
dx = diff(data,1,1);
dy = diff(data,1,2);
mean_gradient = [mean(dx(:)) mean(dy(:))]
assuming equal spacing of the parameters of cours, else you'll have to divide dx and dy by the step sizes.
For the data you provided, this results in:
mean_gradient =
-0.26381 -0.26381
which matches the plot you've made that shows that the function is monotonically decreasing and symmetric in the parameters.

One way to do this is to perform multiple linear regression, for example by using regress.
A two-dimensional regression is a best-fit plane, from which you can calculate a slope value. The link has a nice example with code and a plot of the results.

Related

Poor performance help- muti-class classification by ANN

I'm implementing a 7-class classification task with normalised features and one-hot encoded labels. However, the training and validation accuracies have been extremely poor.
As shown, I normalised features from with StandardScaler() method and each feature vector turns out a 54-dim numpy array. Also, I one-encoded labels in the following manner.
As illustrated below, the labels are (num_y, 7) numpy arrays.
My network architecture:
It is shown here how I designed my model. And I'm wonder if the poor result has something to do with the selection of loss function (I've been using Categorical Cross-Entropy)
I appreciate any response from you. Thanks a lot!
The use of accuracy is obviously wrong. The code I refer to is not provided in your question, but I can speculate that you are comparing the true labels with your model outputs. Your model probably returns a vector of dimensionality 7 which constitutes a probability density function over the classes (due to the softmax activation in your final layer) like this:
model returns: (0.7 0 0.02 0.02 0.02 0.04 0.2) -- they sum to 1 because they represent probabilities
and then you are comparing these numbers with: (1 0 0 0 0 0 0)
what you have to do is translate the model output to the corresponding predicted label ((0.7 0 0.02 0.02 0.02 0.04 0.2) corresponds to (1 0 0 0 0 0 0) because the first output neuron has the larger value (0.7)). You may do that by applying a max function after your model outputs.
To make sure thats whats wrong with your problem formulation print the vector you are comparing with the true labels to get your accuracy and check if they are 7 numbers that sum up to 1.

ACS712 Current Sensor Data Plot using MATLAB and Arduino

I am working on a GUI to plot ac712 current data to MATLAB GUI. The problem is I cannot plot the data properly. The plot seems to be triangular and not sinusoidal curve. Also the current values are correct but I think x-axis values are incorrect. Please help.
clear all
clc
a = arduino('com3','uno');
samples = 200
for i = 1:201
x = [0:0.001:2];
y = zeros(1,201);
b = a.readVoltage(0);
y(i) = ((b-2.5)/.234);
i = i+1
pause (0.006)
end
figure(1)
plot(x,y)
Fig. Plot obtained using MATLAB
When I use arduino only for the same, the values for current are as follows:
0.46
-0.69
1.04
-0.94
0.81
-0.29
-0.06
0.71
-0.83
1.08
-0.81
0.62
0.04
-0.31
0.87
-0.87
1.1
-0.67
0.37
0.27
-0.56
1.02
-0.92
0.94
-0.46
0.08
0.52
-0.71
1.04
which when plotted using Excel is as follows:
Fig. Plot obtained with Arduino current data and x axis values as: 1-29
Are the time scales of both graphs the same?
What is the frequency of the signal you are trying to read?
Because the ACS712 uses chopper stabilization, the output signal is similar to your plot.
You may need to add or change the capacitor between the filter input pin and ground as shown on the typical application figure on the front page of the ACS712 datasheet.

Deconvolution of timeseries matrix Matlab/R

I have a matrix of N rows of time-series data. There is a specific noise contaminating measurement of the data that I have some information about.
The noise in the data can be modeled as a poisson distribution that blurs signal from a given column in the matrix to adjacent columns. For example, if the original data should be a single peak surrounded by no signal:
0 0 0 1 0 0 0
The measured signal distributed slightly asymmetrically resulting in something like this:
0.001 0.005 0.1 0.5 0.2 0.001 0
If I have a good model of how the noise is distributing the data between the columns, how can I use this information to deconvolve the matrix into an approximation of the original signal?

How to filter out unwanted data and noise for parabolic/polynomial polyfit in Matlab or python

I have a set of data that I need to find a best fit polynomial for. Currently I am using python's polyfit, but there are obvious outliers (when the value drops to 0 on the parabola) that affect my polynomial. How would I go about filtering out the unwanted drops in the data so that I get a best fit parabola that does not include the noise?
There is an obvious parabolic path that I would like to get the polynomial to.
Is there a matlab function that I could use to filter out the noise so polyfit would be a better representation of the parabolic data path?
You can filter a 1D function by convolution.
I used this data set:
y=[0 10 50 80 100 0 100 0 110 0 130 130 0 130 0 110 0 100 0 70 0 50 20 10 0];
And when convoluting with
ones(1,10)/10
like this:
convolved=conv(y,ones(1,10)/10);
and then normalizing it to the same maximal value,
convolved2=convolved*max(y)/max(convolved);
this is the result:
And when convoluting with
convolved=conv(y,ones(1,50)/50);
This is the result (again multiplied by the max of y and divided by the max of convolved):
You just need to adjust the filter the way you need. Hopes that this helps.

How can I do a linear best fit from one point to another in a matrix multiple times in order to detrend a series?

For this type of data I want to do an interpolation like fit from one maxima to a minima and so on, so I can look for superimposed high frequencies:
I have a matrix of values such as:
a=[ 3 7 10 3 1 5 10 5 3 2 4 8 10 7 4 3 4 2 1 4 5 7 10 8 7 6 6 4 3 2];
Now I want to choose the relative and maximum and minimum values such that
a=[ 3 0 10 0 1 0 10 0 0 2 0 0 10 0 0 0 0 0 1 0 0 0 10 0 0 0 0 0 0 2];
I essentially want to fit a straight line from a(1) to a(3) and then from a(3) to a(5) and so on, and then subtract the fit from the data.
I know there is a function "detrend" that uses a breakpoint method it denotes as "bp", and that is the closest thing I found resembling my goal.
If you know of a way MATLAB can do this I will greatly appreciate it, otherwise it seems like I have to write an m-file to do it.
I think what your question is asking for is interpolation between the local minima and local maxima of a time series (what you call the "relative minimum and maximum values".)
See this similar question and add some code that does a linear interpolation between the local minima and maxima.
interp1() will do this handily. There is no need for the input points or the output points to be evenly spaced.
>> x = sort(rand(1,10));
>> y = rand(1,10);
>> plot (x,y,'r.');
>> xx = 0:0.01:1;
>> yy = interp1(x,y,xx);
>> hold on;
>> plot (xx,yy,'b-')
What I think you really want to do is decompose the signal into components based on local time scale. (that is, where the frequencies change with time). Use the empirical mode decomposition. Wavelet methods might be an alternative, but the output of the EMD is very easy to interpret visually.
Incidentally, the plain FFT won't work if applied to the entire length of a signal that is time varying - the FFT assumes a stationary (non-varying) signal.
You need to apply the Short-Time Fourier Transform, which is the FFT applied over sliding windows of the data to get a picture of frequency over time. See the spectrogram() function.
>> plot (x,y)
>> x=0:0.001:1;
>> y = chirp(x);
>> plot (x,y);
>> figure;
>> spectrogram(y);
There are issues with time vs. frequency resolution of the short-time Fourier transform that limit its application when your sampling rate is low compared to the frequency of the data. It would would be unlikely to work well for the example data you posted a picture of.