I have a T(60000x8) matrix in which I want to do sorting operation.
In Matlab I can create a sub-matrix where I am sorting the rows that have same value in column 8.
a1 = max(T(:,8)); x = [1.0:1:a1];
for i = 1.0:1:a1
T1 = T(T(:, 8)== x(i), :);
end
This works perfectly and does my job.
But I want to perform the similar operation using Fortran.
I have tried the followings:
read(7,*) *(height(i,j),j=1,8)
k=maxval(height(:,8))
a1 = int(height(:,8))
allocate(x(k), T1(k,8))
do i=1,k
x(i) = i
end do
do i = 1, k
T1 = height((a1(i)== x(i)),:)
end do
When compiling this gives me error
Error: Array index at (1) must be of INTEGER type, found LOGICAL
Fortran is not Matlab ;)... Matlab has a feature to extract a subarrays using booleans, Fortran has not. However Fortran has a sub-array indexing feature.
Your code has many flaws, and I have to assume that height and T1 are real arrays. You can obtain your desired result (at least what I understand you want) with:
integer :: i
integer, allocatable :: idx(:)
real, allocatable :: x(:), T1(:,:)
a1 = nint(height(:,8))
x = [(i,i=1,size(a1))]
idx = pack( x, mask=(a1==x) )
T1 = height(idx(:),:)
Explanation, for instance:
a1 : [4 2 3 1 5]
x : [1 2 3 4 5]
(a1 == x) : [F T T F T]
idx : [ 2 3 5] ! 3 elements
T1 will be made of the columns 2, 3, 5 of height
Related
How the game works is that there is a 3-digit number, and you have to guess it. If you guess a digit in the right spot, you get a strike, and if you guess a digit but in the wrong spot you get a ball. I've coded it like this.
x = random.randint(1, 9)
y = random.randint(1, 9)
z = random.randint(1, 9)
userguessunlisted = input('What number do you want to guess?')
numbertoguess = list[x, y, z]
userguess = list(userguessunlisted)
b = 0
s = 0
while 0 == 0:
if userguess[0] == numbertoguess[0]:
s = s + 1
if userguess[0] == numbertoguess[1]:
b = b + 1
if userguess[0] == numbertoguess[2]:
b = b + 1
if userguess[1] == numbertoguess[0]:
b = b + 1
if userguess[1] == numbertoguess[1]:
s = s + 1
if userguess[1] == numbertoguess[2]:
b = b + 1
if userguess[2] == numbertoguess[0]:
b = b + 1
if userguess[2] == numbertoguess[1]:
b = b + 1
if userguess[2] == numbertoguess[2]:
s = s + 1
print(s + "S", b + "B")
if s != 3:
b = 0
s = 0
else:
print('you win!')
break
When you said list[x, y, z] on line 5, you used square brackets, which python interprets to be a type annotation. For example, if I wanted to specify that a variable is a list of ints, I could say
my_list_of_ints: list[int] = [1, 2, 3]
I think what you meant to do is create a new list from x, y, and z. One way to do this is
numbertoguess = list([x, y, z])
which is probably what you meant to write. This is valid because the list function takes an iterable as its one and only argument.
However, the list portion is redundant; square brackets on the right-hand side of an assignment statement already means "create a list with this content," so instead you should simply say
numbertoguess = [x, y, z]
A few other notes:
input will return a string, but you are comparing that string to integers further down, so none of the comparisons will ever be true. What you want to say is something like the following:
while True:
try:
userguessunlisted = int(input('What number do you want to guess?'))
except:
continue
break
What this code does is attempts to parse the string returned from input into an int. If it fails to do so, which would happen if the user inputted something other than a valid integer, an exception would be thrown, and the except block would be entered. continue means go to the top of the loop, so the input line runs repeatedly until a valid int is entered. When that happens, the except block is skipped, so break runs, which means "exit the loop."
userguessunlisted is only ever going to contain 1 number as written, so userguess will be a list of length 1, and all of the comparisons using userguess[1] and userguess[2] will throw an IndexError. Try to figure out how to wrap the code from (1) in another loop to gather multiple guesses from the user. Hint: use a for loop with range.
It might also be that you meant for the user to input a 3-digit number all at once. In that case, you can use a list comprehension to grab each character from the input and parse it into a separate int. This is probably a bit complicated for a beginner, so I'll help you out:
[int(char) for char in input('What number do you want to guess?')]
print(s + "S", b + "B") will throw TypeError: unsupported operand type(s) for +: 'int' and 'str'. There are lots of ways to combine non-string types with strings, but the most modern way is using f-strings. For example, to combine s with "S", you can say f"{s}S".
When adding some amount to a variable, instead of saying e.g. b = b + 1, you can use the += operator to more concisely say b += 1.
It's idiomatic in python to use snake_case for variables and Pascal case for classes. So instead of writing e.g. numbertoguess, you should use number_to_guess. This makes your code more readable and familiar to other python programmers.
Happy coding!
I am facing this problem at my companies logistics:
Given array of mixed values
arr = [
v1 => a,
v2 => b,
v3 => c,
v4 => d
]
ordered by priority ASC (v1 is more important than v2, ... etc)
I need to search values in a table t like this:
select * from t where
... And
t.v1 = a And
t.v2 = b And
t.v3 = c And
t.v4 = d
The 3 dots in query are the fixed conditions
If I cant find any value from query, perform same query ignoring the least important value from array
select * from t where
... And
t.v1 = a And
t.v2 = b And
t.v3 = c
Again if value was not found. perform a query ignoring the next least important value
select * from t where
... And
t.v1 = a And
t.v2 = b And
t.v4 = d
The query can ignore all elements from array as last query
select * from t where ...
Repeat that until find at least 1 query result or all elements in array are nulled and no result were found. (return false)
I did my search algorithm using binary numbers to find the value which works like this
binaryValue = (2 ^ arr.lenght) - 1 //(In this case: 2^4-1 = 15)
transform binary 15 in array of boolean exploded = [1, 1, 1, 1] (15 in binary is 1111)
Than make the query considering position 0 of booleanArray exploded if true then Consider value in arr of mixed values and so on
loop from 15 to 0 (the 0 iteration is when the boolean array is [0,0,0,0] and ignores all cases
The sequence will be like this with this logic:
[a, b, c, d] // [1,1,1,1] = 15 (select * from t where ... and v1=a and v2=b and v3=c and v4=d)
[a, b, c] // [1,1,1,0] = 14 (select * from t where ... and v1=a and v2=b and v3=c)
[a, b, d] // [1,1,0,1] = 13 (select * from t where ... and v1=a and v2=b and v4=d)
...
[] // [0,0,0,0] = 0 (select * from t where ...)
The search algorithm works fine but I have a huge problem to performance.
The number of queries performed in this search is arr.length! (fatorial) So when the array is length 4, the worst case scenario performs 24 queries.
if the arr.length is 6 (what is the length I am dealing now in my code in production) the worst case performs 720 queries which is unacceptable.
I need a way to Improve this search. Can someone help me?
Thanks in advance.
I came up to the solution using the concept of row's desirability suggested by #RBarryYoung
Instead of performing multiple queries, I fetch all relevant rows into a datatable (1 query) and for each rows I applied a score based in desirability. (Code side)
Dim dicFields As New Dictionary(Of String, String) From { _
{"v1", a}, _
{"v2", b}, _
{"v3", c}, _
{"v4", d}
}
Dim intScore As Integer = dicFields.Keys.Count
For Each pair As KeyValuePair(Of String, String) In dicFields
lstRow _
.Where(Function(p) p.Item(pair.Key) = pair.Value) _
.ToList() _
.ForEach(Sub(p) p.Item("__Score") += intScore)
intScore -= 1
Next
return lstRow _
.OrderByDescending(Function(p) p.Item("__Score")) _
.FirstOrDefault()
It reduced the complexity of n! to just 1 query and n filters. System are up and running smoothly. Thanks for the help #RBarryYoung
I want to solve the following problem in Haskell:
Let n be a natural number and let A = [d_1 , ..., d_r] be a set of positive numbers.
I want to find all the positive solutions of the following equation:
n = Sum d_i^2 x_i.
For example if n= 12 and the set A= [1,2,3]. I would like to solve the following equation over the natural numbers:
x+4y+9z=12.
It's enough to use the following code:
[(x,y,z) | x<-[0..12], y<-[0..12], z<-[0..12], x+4*y+9*z==12]
My problem is if n is not fixed and also the set A are not fixed. I don't know how to "produce" a certain amount of variables indexed by the set A.
Instead of a list-comprehension you can use a recursive call with do-notation for the list-monad.
It's a bit more tricky as you have to handle the edge-cases correctly and I allowed myself to optimize a bit:
solve :: Integer -> [Integer] -> [[Integer]]
solve 0 ds = [replicate (length ds) 0]
solve _ [] = []
solve n (d:ds) = do
let maxN = floor $ fromIntegral n / fromIntegral (d^2)
x <- [0..maxN]
xs <- solve (n - x * d^2) ds
return (x:xs)
it works like this:
It's keeping track of the remaining sum in the first argument
when there this sum is 0 where are obviously done and only have to return 0's (first case) - it will return a list of 0s with the same length as the ds
if the remaining sum is not 0 but there are no d's left we are in trouble as there are no solutions (second case) - note that no solutions is just the empty list
in every other case we have a non-zero n (remaining sum) and some ds left (third case):
now look for the maximum number that you can pick for x (maxN) remember that x * d^2 should be <= n so the upper limit is n / d^2 but we are only interested in integers (so it's floor)
try all from x from 0 to maxN
look for all solutions of the remaining sum when using this x with the remaining ds and pick one of those xs
combine x with xs to give a solution to the current subproblem
The list-monad's bind will handle the rest for you ;)
examples
λ> solve 12 [1,2,3]
[[0,3,0],[3,0,1],[4,2,0],[8,1,0],[12,0,0]]
λ> solve 37 [2,3,4,6]
[[3,1,1,0],[7,1,0,0]]
remark
this will fail when dealing with negative numbers - if you need those you gonna have to introduce some more cases - I'm sure you figure them out (it's really more math than Haskell at this point)
Some hints:
Ultimately you want to write a function with this signature:
solutions :: Int -> [Int] -> [ [Int] ]
Examples:
solutions 4 [1,2] == [ [4,0], [0,1] ]
-- two solutions: 4 = 4*1^2 + 0*2^2, 4 = 0*1^2 + 1*2^2
solutions 22 [2,3] == [ [1,2] ]
-- just one solution: 22 = 1*2^2 + 2*3^2
solutions 10 [2,3] == [ ]
-- no solutions
Step 2. Define solutions recursively based on the structure of the list:
solutions x [a] = ...
-- This will either be [] or a single element list
solutions x (a:as) = ...
-- Hint: you will use `solutions ... as` here
I want to generate random numbers from a selected distribution in VBA (Excel 2007).
I'm currently using the Analysis Toolpak with the following code:
Application.Run "ATPVBAEN.XLAM!Random", "", A, B, C, D, E, F
Where
A = how many variables that are to be randomly generated
B = number of random numbers generated per variable
C = number corresponding to a distribution
1= Uniform
2= Normal
3= Bernoulli
4= Binomial
5= Poisson
6= Patterned
7= Discrete
D = random number seed
E = parameter of distribution (mu, lambda, etc.) depends on choice for C
(F) = additional parameter of distribution (sigma, etc.) depends on choice for C
But I want to have the random numbers be generated into an array, and NOT onto a sheet.
I understand that where the "" is designates where the random numbers should be printed to, but I don't know the syntax for assigning the random numbers to an array, or some other form of memory storage instead of to a sheet.
I've tried following the syntax discussed at this Analysis Toolpak site, but have had no success.
I realize that VBA is not the ideal place to generate random numbers, but I need to do this in VBA. Any help is much appreciated! Thanks!
Using the inbuilt functions is the key. There is a corresponding version for each of these functions but Poisson. In my presented solution I am using an algorithm presented by Knuth to generate a random number from the Poisson Distribution.
For Discrete or Patterned you obviously have to write your custom algorithm.
Regarding the seed you can place a Randomize [seed] before filling your array.
Function RandomNumber(distribution As Integer, Optional param1 = 0, Optional param2 = 0)
Select Case distribution
Case 1 'Uniform
RandomNumber = Rnd()
Case 2 'Normal
RandomNumber = Application.WorksheetFunction.NormInv(Rnd(), param1, param2)
Case 3 'Bernoulli
RandomNumber = IIf(Rnd() > param1, 1, 0)
Case 4 'Binomial
RandomNumber = Application.WorksheetFunction.Binom_Inv(param1, param2, Rnd())
Case 5 'Poisson
RandomNumber = RandomPoisson(param1)
Case 6 'Patterned
RandomNumber = 0
Case 7 'Discrete
RandomNumber = 0
End Select
End Function
Function RandomPoisson(ByVal lambda As Integer) 'Algorithm by Knuth
l = Exp(-lambda)
k = 0
p = 1
Do
k = k + 1
p = p * Rnd()
Loop While p > l
RandomPoisson = k - 1
End Function
Why not use the inbuilt functions?
Uniform = rnd
Normal = WorksheetFunction.NormInv
Bernoulli = iif(rnd()<p,0,1)
Binomial = WorksheetFunction.Binomdist
Poisson = WorksheetFunction.poisson
Patterned = for ... next
Discrete =
-
select case rnd()
case <0.1
'choice 1
case 0.1 to 0.4
'choice 2
case >0.4
'choice 3
end select
Here's a simple program that blows my heap to Kingdom Come:
intersect n k z s rs c
| c == 23 = rs
| x == y = intersect (n+1) (k+1) (z+1) (z+s) (f : rs) (c+1)
| x < y = intersect (n+1) k (z+1) s rs c
| otherwise = intersect n (k+1) z s rs c
where x = (2*n*n) + 4 * n
y = (k * k + k )
f = (z, (x `div` 2), (z+s))
p = intersect 1 1 1 0 [] 0
main = do
putStr (show p)
What the program does is calculate the intersection of two infinite series, stopping when it reaches 23 elements. But that's not important to me.
What's interesting is that as far as I can tell, there shouldn't be much here that is sitting on the heap. The function intersect is recursives with all recursions written as tail calls. State is accumulated in the arguments, and there is not much of it. 5 integers and a small list of tuples.
If I were a betting person, I would bet that somehow thunks are being built up in the arguments as I do the recursion, particularly on arguments that aren't evaluated on a given recursion. But that's just a wild hunch.
What's the true problem here? And how does one fix it?
If you have a problem with the heap, run the heap profiler, like so:
$ ghc -O2 --make A.hs -prof -auto-all -rtsopts -fforce-recomp
[1 of 1] Compiling Main ( A.hs, A.o )
Linking A.exe ...
Which when run:
$ ./A.exe +RTS -M1G -hy
Produces an A.hp output file:
$ hp2ps -c A.hp
Like so:
So your heap is full of Integer, which indicates some problem in the accumulating parameters of your functions -- where all the Integers are.
Modifying the function so that it is strict in the lazy Integer arguments (based on the fact you never inspect their value), like so:
{-# LANGUAGE BangPatterns #-}
intersect n k !z !s rs c
| c == 23 = rs
| x == y = intersect (n+1) (k+1) (z+1) (z+s) (f : rs) (c+1)
| x < y = intersect (n+1) k (z+1) s rs c
| otherwise = intersect n (k+1) z s rs c
where x = (2*n*n) + 4 * n
y = (k * k + k )
f = (z, (x `div` 2), (z+s))
p = intersect 1 1 1 0 [] 0
main = do
putStr (show p)
And your program now runs in constant space with the list of arguments you're producing (though doesn't terminate for c == 23 in any reasonable time).
If it is OK to get the resulting list reversed, you can take advantage of Haskell's laziness and return the list as it is computed, instead of passing it recursively as an accumulating argument. Not only does this let you consume and print the list as it is being computed (thereby eliminating one space leak right there), you can also factor out the decision about how many elements you want from intersect:
{-# LANGUAGE BangPatterns #-}
intersect n k !z s
| x == y = f : intersect (n+1) (k+1) (z+1) (z+s)
| x < y = intersect (n+1) k (z+1) s
| otherwise = intersect n (k+1) z s
where x = (2*n*n) + 4 * n
y = (k * k + k )
f = (z, (x `div` 2), (z+s))
p = intersect 1 1 1 0
main = do
putStrLn (unlines (map show (take 23 p)))
As Don noted, we need to be careful so that accumulating arguments evaluate timely instead of building up big thunks. By making the argument z strict we ensure that all arguments will be demanded.
By outputting one element per line, we can watch the result being produced:
$ ghc -O2 intersect.hs && ./intersect
[1 of 1] Compiling Main ( intersect.hs, intersect.o )
Linking intersect ...
(1,3,1)
(3,15,4)
(10,120,14)
(22,528,36)
(63,4095,99)
(133,17955,232)
(372,139128,604)
(780,609960,1384)
...