A simple question about torch.einsum function - pytorch

A = torch.randn(5,5)
B = torch.einsum("ii->i",A)
C = torch.einsum("ii",A)
Just I exhibit above,I know the result about B that means getting the diagonal elements.
print("before:",A)
print("after:",B)
print('Why:',C)
results
before: tensor([[-0.2339, 0.2501, -1.1814, 1.4392, -0.5461],
[ 1.4908, 0.0626, -0.6849, -1.3106, 0.1257],
[ 3.3362, -1.7438, 0.3027, 0.4346, 0.6830],
[-0.6183, 0.5965, 1.2653, 1.0319, -0.0670],
[-0.5531, -0.4245, -2.4869, 1.2972, 0.6732]])
after: tensor([-0.2339, 0.0626, 0.3027, 1.0319, 0.6732])
Why: tensor(1.8366)
So,Why tensor C is 1.8366?

Executing torch.einsum("ii", A) is equivalent to torch.einsum("ii->", A), this means the output has no index. You can interpret the output as a rank zero tensor.
So this corresponds to computing the sum of the diagonal elements.

Related

How to iterate a dynamic nested loop over a particular values as its range, in python?

If I take a boolean expression and number of input variables from user, then how can I evaluate the expression (to create its truth table) by using dynamic nested loops instead of doing it like this:
expression= "a and (b or a)"
inputs=2
if inputs==2:
for a in range(0,2):
for b in range(0,2):
x = eval(expression)
print(a,b,x)
if inputs==3:
for a in range(0,2):
for b in range(0,2):
for c in range(0,2):
x = eval(expression)
print(a,b,x)
It limits the number of variables user can evaluate expression on, as I can not write loops manually. I tried using itertools.product() for this, but I don't know how to give values to the iterating variables.
from itertools import product
variables=['a','b','c']
for items in product(*variables):
rows=(eval(expression))
print(rows)
As you can see, it obviously gives error that a,b,c are undefined in eval(expression). How can I iterate each one of them over [0,1] ?
You could do it using itertools.product() simply
import itertools
inputs = int(input())
temp = [[0, 1]] * inputs
for combination in itertools.product(*temp):
print(combination)
I think you were on the right path here and itertools.product() is what you are looking for. The following is a one-liner, but you could expand it if you want. Note that I am not using eval, but rather a list comprehension paired with the already mentioned itertools.product(). Note also that you can use and, or and () in normal code.
import itertools
rows = [a and (b or c) for a, c, b in itertools.product([True, False], [True, False], [True, False])]
print(rows)
If you are using user input, it might make sense to define truthy values.
Also if you want the inputs for the truth-table, you can also do this first:
import itertools
inputs = [[a, b, c] for a, b, c in itertools.product([True, False], [True, False], [True, False])]
rows = [a and (b or c) for a, c, b in inputs]
print(rows)
Edit: If you have a lot of inputs, the logical expression would likely include any() and all().
Edit2: Now I understand what you mean. Here is a full version with a dynamic number of inputs using the above-mentioned any() and all(). In this example of a logical condition, the first half of the array (rounded down if it is an uneven length) needs to be true and at least one of the second half. Feel free to adapt the expression as you see fit. Note that your original expression does not make much sense. If the first part a is Truthy then the second part where you check for a or b is necessarily also Truthy because we already checked for a. That is why I picked a slightly modified version.
import itertools
input_num = int(input())
arrs = [[False, True]] * input_num
inputs = [x for x in itertools.product(*arrs)]
rows = [all(x[:int(len(x)/2)]) and any(x[int(len(x)/2):]) if len(x) > 1 else bool(x) for x in inputs ]
print(rows)

Scala count chars in a string logical error

here is the code:
val a = "abcabca"
a.groupBy((c: Char) => a.count( (d:Char) => d == c))
here is the result I want:
scala.collection.immutable.Map[Int,String] = Map(2 -> b, 2 -> c, 3 -> a)
but the result I get is
scala.collection.immutable.Map[Int,String] = Map(2 -> bcbc, 3 -> aaa)
why?
thank you.
Write an expression like
"abcabca".groupBy(identity).collect{
case (k,v) => (k,v.length)
}
which will give output as
res0: scala.collection.immutable.Map[Char,Int] = Map(b -> 2, a -> 3, c -> 2)
Let's dissect your initial attempt :
a.groupBy((c: Char) => a.count( (d:Char) => d == c))
So, you're grouping by something which is what ? the result of a.count(...), so the key of your Map will be an Int. For the char a, we will get 3, for the chars b and c, we'll get 2.
Now, the original String will be traversed and for the results accumulated, char by char.
So after traversing the first "ab", the current state is "2-> b, 3->c". (Note that for each char in the string, the .count() is called, which is a n² wasteful algorithm, but anyway).
The string is progressively traversed, and at the end the accumulated results is shown. As it turns out, the 3 "a" have been sent under the "3" key, and the b and c have been sent to the key "2", in the order the string was traversed, which is the left to right order.
Now, a usual groupBy on a list returns something like Map[T, List[T]], so you may have expected a List[Char] somewhere. It doesn't happen (because the Repr for String is String), and your list of chars is effectively recombobulated into a String, and is given to you as such.
Hence your final result !
Your question header reads as "Scala count chars in a string logical error". But you are using Map and you wanted counts as keys. Equal keys are not allowed in Map objects. Hence equal keys get eliminated in the resulting Map, keeping just one, because no duplicate keys are allowed. What you want may be a Seq of tuples like (count, char) like List[Int,Char]. Try this.
val x = "abcabca"
x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}
In Scal REPL:
scala> x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}
res13: List[(Int, Char)] = List((2,b), (3,a), (2,c))
The above gives a list of counts and respective chars as a list of tuples.So this is what you may really wanted.
If you try converting this to a Map:
scala> x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}.toMap
res14: scala.collection.immutable.Map[Int,Char] = Map(2 -> c, 3 -> a)
So this is not what you want obviously.
Even more concisely use:
x.distinct.map(v=>(x.filter(_==v).size,v))
scala> x.distinct.map(v=>(x.filter(_==v).size,v))
res19: scala.collection.immutable.IndexedSeq[(Int, Char)] = Vector((3,a), (2,b), (2,c))
The problem with your approach is you are mapping count to characters. Which is:
In case of
val str = abcabca
While traversing the string str a has count 3, b has count 2 and c has count 2 while creating the map (with the use of groupBy) it will put all the characters in the value which has the same key that is.
Map(3->aaa, 2->bc)
That’s the reason you are getting such output for your program.
As you can see in the definition of the groupBy function:
def
groupBy[K](f: (A) ⇒ K): immutable.Map[K, Repr]
Partitions this traversable collection into a map of traversable collections according to some discriminator function.
Note: this method is not re-implemented by views. This means when applied to a view it will always force the view and return a new traversable collection.
K
the type of keys returned by the discriminator function.
f
the discriminator function.
returns
A map from keys to traversable collections such that the following invariant holds:
(xs groupBy f)(k) = xs filter (x => f(x) == k)
That is, every key k is bound to a traversable collection of those elements x for which f(x) equals k.
GroupBy returns a Map which holds the following invariant.
(xs groupBy f)(k) = xs filter (x => f(x) == k)
Which means it return collection of elements for which the key is same.

Not showing output python, no error showing

Let us consider polynomials in a single variable x with integer coefficients: for instance, 3x^4 - 17x^2 - 3x + 5. Each term of the polynomial can be represented as a pair of integers (coefficient,exponent). The polynomial itself is then a list of such pairs.
We have the following constraints to guarantee that each polynomial has a unique representation:
Terms are sorted in descending order of exponent
No term has a zero coefficient
No two terms have the same exponent
Exponents are always nonnegative
For example, the polynomial introduced earlier is represented as
[(3,4),(-17,2),(-3,1),(5,0)]
The zero polynomial, 0, is represented as the empty list [], since it has no terms with nonzero coefficients.
Write Python functions for the following operations:
addpoly(p1,p2) ?
def addpoly(p1,p2):
p1=[]
p2=[]
for i in range(0,len(p1)):
for j in range(0,len(p2)):
L=[]
if p1[i][1]==p2[j][1]:
L=L[p1[i][0]+p2[j][0]][p1[i][1]]
elif p1[i][1]!=p2[j][1]:
L=L+p1[i][j]
L=L+p2[i][j]
print("L")
You are reassigning the p1 and p2 arguments to empty lists at the top of your function. This means you will always be checking for i in range(0, 0), which is an empty range. In other words, nothing in your loop will be executed. This is why you are not seeing any output. You are not seeing any error messages, because there is nothing wrong with your syntax, the problem is with the logic.
My math skills are nonexistent, so I cannot comment on the accuracy of most of the logic in your code, but for sure you need to get rid of the first two lines of your function (p1 = [] and p2 = []) or your function will do nothing.
Also, make sure to print the variable L rather than the string "L" to print your list:
print(L)
try this code
def addpoly(p1,p2):
L=[]
for i in range(0,len(p1)):
for j in range(0,len(p2)):
if p1[i][1] == p2[j][1] and p1[i][0]+p2[j][0] != 0 :
L.append((p1[i][0]+p2[j][0],p1[i][1]))
elif p1[i][1] == p2[j][1] and p1[i][0]+p2[j][0] == 0 :
pass
elif i == j:
L.append(p2[i])
L.append(p1[i])
return (L)

construction of state machine in string maching in book algorithm by CLRS

Below is text from Introduction to Algorithms by CLRS. Below is code snippet in string matching using finite state automata. Trnstion function is used to construct state table with pattern to be searched.
Computing the transition function:
The following procedure computes the transition function sigma from a given pattern
P [1: :m].
COMPUTE-TRANSITION-FUNCTION.
1 m = P:length
2 for q = 0 to m
3 for each character a belongs to alphabetset
4 k = min (m + 1, q + 2)
5 repeat
6 k = k - 1
7 until Pk is suffix Pqa
8 sigma(q, a) = k
9 return sigma
This procedure computes sigma(q, a) in a straightforward manner according to its definition
in equation (32.4). The nested loops beginning on lines 2 and 3 consider all states q and all characters a,
and lines 4–8 set sigma(q, a) to be the largest k such
that Pk is suffix Pqa. The code starts with the largest conceivable value of k, which is
min(m, q+1). It then decreases k until Pk is suffix Pqa, which must eventually occur,since P0 is empty string which
is a suffix of every string.
My questions on above code
Why author is selecting k as min(m + 1, q+2) at line 4?
In below explantion text author is mentions that "The code starts with the largest conceivable value of k, which is
min(m, q+1)." Which is not matching with pseudo code above at line 4?
Request to explain with simple example and steps of psudoe code while answering above questions.

Haskell not in scope list comprehension

all_nat x = [ls| sum ls == x]
I'd like to write a function that given an integer x it returns all the lists that the result of their elements when summed is the integer x but I always get the error "not in scope: 'ls' " for both times it apperas. I'm new to haskell. What's the syntax error here?
The problem is that you need to define all used variables somewhere, but ls is undefined. Moreover, it can't be defined automatically, because the compiler doesn't know about the task — how the list should be generated? Ho long can it be? Are terms positive or not, integral or not? Unfortunately your code definition of the problem is quite vague for modern non-AI languages.
Let's help the compiler. To solve such problems, it's often useful to involve some math and infer the algorithm inductively. For example, let's write an algorithm with ordered lists (where [2,1] and [1,2] are different solutions):
Start with a basis, where you know the output for some given input. For example, for 0 there is only an empty list of terms (if 0 could be a term, any number could be decomposed as a sum in infinitely many ways). So, let's define that:
allNats 0 = [[]] --One empty list
An inductive step. Assuming we can decompose a number n, we can decompose any number n+k for any positive k, by adding k as a term to all decompositions of n. In other words: for numbers greater than 0, we can take any number k from 1 to n, and make it the first term of all decompositions of (n­-k):
allNats n = [ k:rest --Add k as a head to the rest, where
| k <- [1 .. n] --k is taken from 1 to n, and
, rest <- allNats (n - k)] --rest is taken from solutions for (n—k)
That's all! Let's test it:
ghci> allNat 4
[[1,1,1,1],[1,1,2],[1,2,1],[1,3],[2,1,1],[2,2],[3,1],[4]]
Let's break this up into two parts. If I've understood your question correctly, the first step is to generate all possible (sub)lists from a list. There's a function to do this, called subsequences.
The second step is to evaluate the sum of each subsequence, and keep the subsequences with the sum you want. So your list comprehension looks like this:
all_nat x = [ls| ls <- subsequences [1..x], sum ls == x]
What about
getAllSums x = [(l,r)| l <- partial_nat, r <- partial_nat, l + r == x ]
where partial_nat = [1..x]

Resources