Script to calculate the product of numbers in all possible combinations - arrays

I have a db of numbers (percentages) which I want to calculate the product for each of the possible combinations of all the numbers and their difference from a 100%.
So for example, for the following numbers:
0.3, 0.4, 0.6, 0.7
I want to calculate the following:
(1-0.3)*(1-0.4)*(1-0.6)*(1-0.7)
0.3*0.4*0.6*0.7
0.3*(1-0.4)*(1-0.6)*(1-0.7)
(1-0.3)*(1-0.4)*(1-0.6)*0.7
(1-0.3)*0.4*(1-0.6)*(1-0.7)
(1-0.3)*(1-0.4)*0.6*(1-0.7)
0.3*(1-0.4)*(1-0.6)*0.7
0.3*(1-0.4)*0.6*(1-0.7)
(1-0.3)*(1-0.4)*0.6*0.7
(1-0.3)*0.4*(1-0.6)*0.7
(1-0.3)*0.4*0.6*(1-0.7)
0.3*0.4*(1-0.6)*(1-0.7)
(1-0.3)*0.4*0.6*0.7
0.3*(1-0.4)*0.6*0.7
0.3*0.4*(1-0.6)*0.7
0.3*0.4*0.6*(1-0.7)
I want to be able to build this for any n numbers (here I gave an example for 4 numbers, but there can be hundreds and thousands of these). How is it called? Is there a command for them? Is there a known script somewhere?
In the end I will need to sum them all up. And use them individually as well.

I do not think there is a pre-defined command for this in any language, but most languages will allow you to write a recursive function for this. For example, in Haskell you could use:
calculate [] = [[]]
calculate (x:xs) = let rec = calculate xs
pos = map (x:) rec
neg = map ((1 - x):) rec
in pos ++ neg
You can try this out here and run your example with the line:
main = print (calculate [0.3, 0.4, 0.6, 0.7])
Note that this calculate function takes a list of percentages as input and returns a list of lists, each of which represents a line in your desired result. This result can then be used to calculate your intermediate and final result.
The function works as follows. If your input is an empty list, return a list with an empty list. If the input has elements, separate the first element (x) from the remainder of the list (xs) and calculate the result on the remainder of the list. The result of this is a list with lists of percentages which is stored in rec.
To calculate the result value, prepend x to each list in rec (stored in pos) and prepend 1-x to each list in rec (stored in neg). As the result we return one list which is the concatenation of pos and neg.

Related

How to count for 2 different arrays how many times the elements are repeated, in MATLAB?

I have array A (44x1) and B (41x1), and I want to count for both arrays how many times the elements are repeated. And if the repeated values are present in both arrays, I want their counting to be divided (for instance: value 0.5 appears 500 times in A and 350 times in B, so now divide 500 by 350).
I have to do this for bigger arrays as well, so I was thinking about using a looping (but no idea how to do it on MATLAB).
I got what I want on python:
import pandas as pd
data1 = pd.read_excel('C:/Users/Desktop/Python/data1.xlsx')
data2 = pd.read_excel('C:/Users/Desktop/Python/data2.xlsx')
for i in data1['Mag'].value_counts() & data2['Mag'].value_counts():
a = data1['Mag'].value_counts()/data2['Mag'].value_counts()
print(a)
break
Any idea of how to do the same on MATLAB? Thanks!
Since you can enumerate all valid earthquake magnitude values, you could use:
% Make up some data
A=randi([2 58],[100 1])/10;
B=randi([2 58],[20 1])/10;
% Round data to nearest tenth
%A=round(A,1); %uncomment if necessary
%B=round(B,1); %same
% Divide frequencies
validmags=0.2:0.1:5.8;
Afreqs=sum(double( abs(A-validmags)<1e-6 ),1); %relies on implicit expansion; A must be a column vector and validmags must be a row vector; dimension argument to sum() only to remind user; double() not really needed
Bfreqs=sum(double( abs(B-validmags)<1e-6 ),1); %same
Bfreqs./Afreqs, %for a fancier version: [{'Magnitude'} num2cell(validmags) ; {'Freq(B)/Freq(A)'} num2cell(Bfreqs./Afreqs)].'
The last line will produce NaN for 0/0, +Inf for nn/0, and 0 for 0/nn.
You could also use uniquetol, align the unique values of each vector, and divide the respective absolute frequencies. But I think the above approach is cleaner and easier to understand.

Using equations with slicing through numpy arrays Pythopn

I am trying to write an equation where it calculates the sum of the previous index and the current index and then divides it by the current index. So the equation (Current value+ previous value)/previous value) would output (52599 + 52575)/52575 for the first two values (52599 52575) and then (52575 + 52598)/52598 for the next two values (52575, 53598) and so on. I do not know how I can go about doing this.
Numbers = np.array([ 52599 52575 53598 336368 336875 337466 338292 356587 357474 357763 358491 358659 359041 360179 360286])
Equation = (Current value+ previous value)/previous value)
This is what you need:
numbers = np.array([52599, 52575, 53598, 336368, 336875, 337466, 338292, 356587, 357474, 357763, 358491, 358659, 359041, 360179, 360286])
result = (numbers[:-1] + numbers[1:]) / numbers[1:]
result
>>>
array([2.00045649, 1.98091347, 1.15934334, 1.99849499, 1.99824871,
1.99755832, 1.94869415, 1.9975187 , 1.9991922 , 1.99796927,
1.99953159, 1.99893605, 1.99684046, 1.99970301])
BTW, please use all lowercase and underscore (snake case) for variable names. This is more pythonic.

Roman Number Calculator

I have to make an assignment wherein I have to implement the Roman Numerals along with the rules that are followed while doing calculations on them, contained in this link
http://www.periodni.com/roman_numerals_converter.html
I don't want the code, just help. I have gone with two approaches till now:
Using constants, I have declared the roman numerals as constants, and then after getting the input, I am left with the choice to decode the string input, which I later dropped.
Using hash. I have declared a hash with the numerals, then after getting the input, I am converting the string using to_sym method into there corresponding value. After this, I have taken an array containing the decimals of the roman numerals, and I intend to compare those with the input.
I am stuck at this part. I don't know how to compare here. Also, I don't want to sort the input array, because then calculations would go wrong.
Can anyone help me with how to proceed? Not the code, just steps.
This is what I have done so far:
class Conversion
hash ={ :I => 1, :V => 5, :X => 10, :L => 50, :C => 100, :D => 500, :M => 1000}
result = 0
value = []
hash_values = hash.values
puts "enter input string"
input = gets.chomp.upcase.split(//)
input.each do |i|
value <<  hash[i.to_sym]
end
for i in value do
if value[i] > value[i+1]
result = result + value[i]
else
result = result + (value[i+1] - value[i])
end
end
puts result
end
If u run the code, you'll see that while I try to compare in the last loop it is taking the index for calculations. Same happened when I tried doing the same using two hashes. I can't use any gem or external libraries cause that is the requirement.
The idea is to create a tree where every node have two childrens: the left one is what to substract and the right one is what to add.
Once you get a string, you find the most valued letter and make it the first node like this:
XLIX
L
/ \
X IX
Then you run this function recursively on the children nodes until the node is trivial (like XX or III).
The final step is to recursively calculate the result.

Plot Representative sample of large data set - Matlab

I have a large data set with two arrays, say x and y. The arrays have over 1 million data points in size. Is there a simple way to do a scatter plot of only 2000 of these points but have it be representative of the entire set?
I'm thinking along the lines of creating another array r ; r = max(x)*rand(2000,1) to get a random sample of the x array. Is there a way to then find where a value in r is equal to, or close to a value in x ? They wouldn't have to be in the same indexed location but just throughout the whole matrix. We could then plot the y values associated with those found x values against r
I'm just not sure how to code this. Is there a better way than doing this?
I'm not sure how representative this procedure will be of your data, because it depends on what your data looks like, but you can certainly code up something like that. The easiest way to find the closest value is to take the min of the abs of the difference between your test vector and your desired value.
r = max(x)*rand(2000,1);
for i = 1:length(r)
[~,z(i)] = min(abs(x-r(i)));
end
plot(x(z),y(z),'.')
Note that the [~,z(i)] in the min line means we want to store the index of the minimum value in vector z.
You might also try something like a moving average, see this video: http://blogs.mathworks.com/videos/2012/04/17/using-convolution-to-smooth-data-with-a-moving-average-in-matlab/
Or you can plot every n points, something like (I haven't tested this, so no guarantees):
n = 1000;
plot(x(1:n:end),y(1:n:end))
Or, if you know the number of points you want (again, untested):
npoints = 2000;
interval = round(length(x)/npoints);
plot(x(1:interval:end),y(1:interval:end))
Perhaps the easiest way is to use round function and convert things to integers, then they can be compared. For example, if you want to find points that are within 0.1 of the values of r, multiply the values by 10 first, then round:
r = max(x) * round(2000,1);
rr = round(r / 0.1);
xx = round(x / 0.1);
inRR = ismember(xx, rr)
plot(x(inRR), y(inRR));
By dividing by 0.1, any values that have the same integer value are within 0.1 of each other.
ismember returns a 1 for each value of xx if that value is in rr, otherwise a 0. These can be used to select entries to plot.

Splitting an array into n parts and then joining them again forming a histogram

I am new to Matlab.
Lets say I have an array a = [1:1:1000]
I have to divide this into 50 parts 1-20; 21-40 .... 981-1000.
I am trying to do it this way.
E=1000X
a=[1:E]
n=50
d=E/n
b=[]
for i=0:n
b(i)=a[i:d]
end
But I am unable to get the result.
And the second part I am working on is, depending on another result, say if my answer is 3, the first split array should have a counter and that should be +1, if the answer is 45 the 3rd split array's counter should be +1 and so on and in the end I have to make a histogram of all the counters.
You can do all of this with one function: histc. In your situation:
X = (1:1:1000)';
Edges = (1:20:1000)';
Count = histc(X, Edges);
Essentially, Count contains the number of elements in X that fall into the categories defined in Edges, where Edges is a monotonically increasing vector whose elements define the boundaries of sequential categories. A more common example might be to construct X using a probability density, say, the uniform distribution, eg:
X = 1000 * rand(1000, 1);
Play around with specifications for X and Edges and you should get the idea. If you want the actual histogram plot, look into the hist function.
As for the second part of your question, I'm not really sure what you're asking.

Resources