text:
# ☑ Python 2to3: What’s New in 3.3 - Part 1

6 Mar 2021 at 11:11PM in Software
｜   ｜

The fourth Python 3.x release brought another slew of great new features. So many, in fact, that I’ve split this release into two articles, of which this is the first. Highlights in this part include yield from expressions, mocking support in unittest and virtualenv suppport in the standard library.

This is part 4 of the “Python 2to3” series of posts:

The next release in this sequence of articles is Python 3.3, which was released just over 19 months after version 3.2. This one was another packed release and it contained so many features I decided to split this into two articles. In this first one we’ll be covering yield from expressions which allow generators to delegate for each other, support for mocking built in to the standard library, the venv module, and a host of diagnostic improvements.

## Builtin Virtual Environments¶

If you’ve been using Python for a decent length of time, you’re probably familiar with the virtualenv tool written by prolific Python contributor Ian Bicking1 around thirteen years ago. This was the sort of utility that you instantly wonder how you managed without it before, and it’s become a really key development2 tool for many Python developers.

As an acknowledgement of its importance, the Python team pulled a subset of its functionality into the standard Python library as the new venv module, and exposed a command-line interface with the pyvenv script. This is fully detailed in PEP 405.

On the face of it, this might not seem to be all that important, since virtualenv already exists and does a jolly good job all round. However, I think there are a whole host of benefits which make this stategically important. First and foremost, since it’s part of the standard distribution, there’s little chance that the core Python developers will make some change that renders it incompatible on any supported platform. It can also probably benefit from internal implementation details of Python on which an external project couldn’t safely rely, which may enable greater performance and/or reliability.

Secondly, the fact that it’s installed by default means that project maintainers have a baseline option they can count on, for installation or setup scripts, or just for documentation. This will not doubt cut down on support queries from inexperienced users who wonder why this virtualenv command isn’t working.

Thirdly, this acts as defense against the forking of the project, which is always a background concern with open source. It’s not uncommon for one popular project to be forked and taken in two divergent directions, and then suddenly project maintainers and users alike need to worry about which one they’re going with, the support efforts of communitieis are split, and all sorts of other annoyances. Having standard support in the standard library means there’s an option that can be expected to work in all cases.

In any case, regardless of whether you feel this is an important feature or just a minor tweak, it’s at least handy to have venv always available on any platform where Python is installed.

As an aside, if you’re curious about how virtualenv works then Carl Meyer presented an interesting talk on the subject, of which you can find the video and sildes online.

## Generator Delegation¶

I actually already discussed this topic fairly well in my first article in my series on coroutines in Python a few years ago. But to save you the trouble of reading all that, or the gory details in PEP 380, I’ll briefly cover it here.

This is a fairly straightforward enhancement for generators to yield control to each other, which is performed using the new yield from statement. It’s perhaps best explained with a simple example:

>>> def fun2():
...     yield from range(10)
...     yield from range(30, 20, -2)
...
>>> list(fun2())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 30, 28, 26, 24, 22]

On the face of it this is just a simple shorthand for for i in iter: yield i. However, there’s rather more to it when you consider the coroutine-like features that generators have where you can pass values into them, since these values also need to be routed directly to the delegate generator as well as the yielded values being routed back out.

There’s also an enhancement to generator return values. Previously the use of return within a generator was simply a way to terminate the generator, raising StopIteration, and it was a syntax error to provide an argument to the return statement. As of Python 3.3, however, this has been relaxed and a value is permitted. The value is returned to the called by attaching it to the StopIteration exception, but where yield from is used then this becomes the value to which the yield from expression evaluates.

This may seem a bit abstract and hard to grasp, so I’ve included an example of using these features for parsing HTTP chunk-encoded bodies. This is a format used for HTTP responses if the sender doesn’t know the size of the response up front, where the data is split into chunks of a known size and the length of a chunk is sent first followed by the data. This means the sender can keep transmitting data until it’s exhausted, and the reader can be processing it parallel. The end of the data is indicated by an empty chunk.

This sort of message-based interpretation of data from a byte stream is always a little fiddly. It’s most efficient to read in large chunks from the socket, and in the case of a chunk header you don’t know many bytes it’s going to be anyway, since the length is variable number of digits. As a result, by the time you’ve read the data you need, the chances are your buffer already contains some of the next piece of data. If you want to structure your code well and split parsing the various pieces up into multiple functions, as the single responsibility principle suggests, then this means you’ve always got this odd bit of “overflow” data as the initial set to parse before reading more from the data source.

There’s also the aspect that it’s nice to decouple the parsing from the data source. For example, although you’d expect a HTTP response to generally come in from a socket object, there’ll always be someone who already has it in a string form and still wants to parse it — so why force them to jump through some hoops making their string look like a file object again, when you could just structure your code a little more elegantly to decouple the parsing and I/O?

For all of the above reasons, I think that generators make a fairly elegant solution to this issue. Take a look at the code below and then I’ll explain why it works and why I think this is potentially a useful approach.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 def content_length_decoder(length, data=b""): """Can be used directly by requests with Content-Length header.""" while len(data) < length: length -= len(data) data = yield data new_input = yield data[:length] return data[length:] + new_input def chunked_decoder(data=b""): """Decodes HTTP bodies with chunked encoding.""" while True: crlf_index = data.find(b"\r\n") if crlf_index < 0: # Loop until we have CRLF chunk header. data += yield b"" continue chunk_len = int(data[:crlf_index], 16) if chunk_len == 0: # Zero length chunk terminates body. return data[crlf_index+2:] chunk = content_length_decoder(chunk_len, data[crlf_index+2:]) data = yield from chunk # Strip off trailing CRLF from end of chunk. while len(data) < 2: data += yield b"" data = data[2:] # This is an example of a chunk-encoded response, with the headers # already stripped off. body_pieces = (b"C\r\nStrange", b" wome\r\n1B\r\nn lying in", b" ponds, distribut\r\n13\r", b"\ning swords, is no b\r\n", b"20\r\nasis for a system of ", b"government!\r\n0\r\n\r\n") decoder = chunked_decoder() document = bytearray(next(decoder)) try: for input_piece in body_pieces: document += decoder.send(input_piece) document += decoder.send(b"") except StopIteration as exc: # Generally expect this to be the final terminating CRLF, but HTTP # standard allows for "trailing headers" here. print("Trailing headers: " + repr(exc.value)) print("Document: " + repr(document))

The general idea here is that each generator parses data which is passed to it via its send() method. It processes input until its section is done, and then it returns control to the caller. Ultimately decoded data is yielded from the generators, and each one returns any unparsed input data via its StopIteration exception.

In the example above you can see how this allows content_length_decoder() to be factored out from chunked_decoder() and used to decode each chunk. This refactoring would allow a more complete implementation to reuse this same generator to decode bodies which have a Content-Length header instead of being sent in chunked encoding. Without yield from this delegation wouldn’t be possible unless orchestrated by the top-level code outside of the generators, and that breaks the abstraction.

This is just one example of using generators in this fashion which sprung to mind, and I’m sure there are better ones, but hopefully it illustrates some of the potential. Of course, there are more developments on coroutines in future versions of Python 3 which I’ll be looking at later in this series, or if you can’t wait then you can take a read through my earlier series of articles specifically on the topic of coroutines.

## Unit Testing¶

The major change in Unit Testing in Python 3.3 is that the mocking library has been merged into the standard library as unittest.mock. A full overview of this library is way beyond the scope of this article, so I’ll briefly touch on the highlights with some simple examples.

The core classes are Mock and MagicMock, where MagicMock is a variation which has some additional behaviours around Python’s magic methods4. These classes will accept requests for any attribute or method call, and create a mock object to track accesses to them. Afterwards, your unit test can make assertions about which methods were called by the code under test, including which parameters were passed to them.

One aspect that’s perhaps not immediately obvious is that these two objects represet more or less any object, such as functions or classes. For example, if you create a Mock instance which represents a class and then access a method on it, a child Mock object represents that method. This is possible in Python since everything comes down to attribute access at the end of the day — it just happens that calling a method queries an attribute __call__ on the object. Python’s duck-typing approach means that it doesn’t care whether it’s a genuine function that’s being called, or an object which implements __call__ such as Mock.

Here’s a short snippet which shows that without any configuration, a Mock object can be used to track calls to methods:

>>> from unittest import mock
>>> m = mock.Mock()
>>> m.any_method()
<Mock name='mock.any_method()' id='4352388752'>
>>> m.mock_calls
[call.any_method()]
>>> m.another_method(123, "hello")
<Mock name='mock.another_method()' id='4352401552'>
>>> m.mock_calls
[call.any_method(), call.another_method(123, 'hello')]

Here I’m using the mock_calls attribute, which tracks the calls made, but there are also a number of assert_X() methods which are probably more useful in the context of a unit test. They work in a very similar way to the existing assertions in unittest.

This is great for methods with no return type and are side-effect free, but what about implementing those behaviours? Well, that’s pretty straightforward once you understand the basic structure. Let’s say you have a class and you want to add a method with a side-effect, you just create a new Mock object and assign that as an attribute with the name of the method to the mock that’s representing your object instance. Then you create some function which implements whatever side-effects you require, and you assign that to the special side_effect attribute of the Mock representing your method. And then you’re done:

>>> m = mock.Mock()
>>> m.mocked_method = mock.Mock()
>>> def mocked_method_side_effect(arg):
...     print("Called with " + repr(arg))
...     return arg * 2
...
>>> m.mocked_method.side_effect = mocked_method_side_effect
>>> m.mocked_method(123)
Called with 123
246

Finally, as an illustration of the MagicMock class, you can see from the snippet below that the standard Mock object refuses to auto-create magic methods, but MagicMock implements them in the same way. You can add side-effects and return values to these in the same way as any normal methods.

>>> m = mock.Mock()
>>> len(m)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'Mock' has no len()
>>> mm = mock.MagicMock()
>>> len(mm)
0
>>> mm[123]
<MagicMock name='mock.__getitem__()' id='4352367376'>
>>> mm.mock_calls
[call.__len__(), call.__getitem__(123)]
>>> mm.__len__.mock_calls
[call()]
>>> mm.__getitem__.mock_calls
[call(123)]

That covers the basics of creating mocks, but how about injecting them into your code under test? Well, of course sometimes you can do that yourself by passing in a mock object directly. But often you’ll need to change one of the dependencies of the code. To do this, you can use mock.patch as a decorator around your test methods to overwrite one or more dependencies with mocks. In the example below, the time.time() function is replaced by a MagicMock instance, and the return_value attribute is used to control the time reported to the code under test.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import random import time from unittest import mock class StickyRandom: def __init__(self): self.last_time = 0 def get_value(self): if time.time() - self.last_time > 60: self.last_value = random.random() self.last_time = time.time() return self.last_value @mock.patch("time.time") def test_sticky_random(time_mock): instance = StickyRandom() time_mock.return_value = 1000 value1 = instance.get_value() time_mock.return_value = 1030 value2 = instance.get_value() assert value1 == value2 time_mock.return_value = 1090 value3 = instance.get_value() assert value3 != value1 test_sticky_random()

So that’s it for my whirlwind tour of mocking. There’s a lot more to it than I’ve covered, of course, so do take the time to read through the full documentation.

## Diagnostics Changes¶

There are a few changes which are helpful for exception handling and introspection.

### Nicer OS Exceptions¶

The situation around catching errors in Operating System operations has always been a bit of a mess with too many exceptions covering what are very similar operations at their heart. This can cause all sorts of annoying bugs in error handling if you try to catch the wrong exception.

For example, if you fail to os.remove() a file you get an OSError but if you fail to open() it you get an IOError. So that’s two exceptions for I/O operations right there, but if you happen to be using sockets then you need to also worry about socket.error. If you’re using select you might get select.error, but equally you might get any of the above as well.

The upshot of all this is that for any block of code that does a bunch of I/O you end up having to either catch Exception, which can hide other bugs, or catch all of the above individually.

Thankfully in Python 3.3 this situation has been averted since these have all been collapsed into OSError as per PEP 3151. The full list that’s been rolled into this is:

• OSError
• IOError
• EnvironmentError
• WindowsError
• mmap.error
• socket.error
• select.error

Never fear for your existing code, however, beacuse the old names have all been maintained as aliases for OSError.

As well as this, however, there’s another change that’s even handier. Often you need to only catch some subset of errors and allow others to pass on as true error conditions. A common example of this is where you’re doing non-blocking operations, or you’ve specified some sort of timeout, and you want to ignore those cases but still catch other errors. In these cases, you often find yourself branching on errno like this:

  1 2 3 4 5 6 7 8 9 10 11 12 import errno def reliable_send(data, sock): while data: try: sent = sock.send(data) data = data[sent:] except socket.error as exc: if exc.errno == errno.EINTR: continue else: raise

It’s not terrible, but breaks the usual idiom of each error being its own exception, and make things just that bit harder to read.

Python 3.3 to the rescue! New exception types have been added which are derivations of OSError and correspond to the more common of these error cases, so they can be caught more gracefully. The new exceptions and the equivalent errno codes are:

New Exception Errno code(s)
BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
ChildProcessError ECHILD
FileExistsError EEXIST
FileNotFoundError ENOENT
InterruptedError EINTR
IsADirectoryError EISDIR
NotADirectoryError ENOTDIR
PermissionError EACCES, EPERM
ProcessLookupError ESRCH
TimeoutError ETIMEDOUT
ConnectionError A base class for the remaining exceptions…
… BrokenPipeError EPIPE, ESHUTDOWN
… ConnectionAbortedError ECONNABORTED
… ConnectionRefusedError ECONNREFUSED
… ConnectionResetError ECONNRESET

The BlockingIOError exception also has a handy characters_written attribute, when using buffered I/O classes. This indicates how many characters were written before the filehandle became blocked.

To finish off this setion, here’s a small example of how this might make code more readable. Take this code to handle a set of different errors which can occur when opening and attempting to read a particular filename:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import errno try: # ... except (IOError, OSError) as exc: if exc.errno == errno.EISDIR: print("Can't open directories") elif exc.errno in (errno.EPERM, errno.EACCES): print("Permission error") else: print("Unknown error") except UnicodeDecodeError: print("Unicode error") except Exception: print("Unknown error")

Particularly unpleasant here is the code duplication between handling unmatched errno codes and random other exceptions — although that’s just the duplication of a print() in this example, in reality that could become significant code duplication. With the new exceptions introduced in Python 3.3, however, this is all significantly cleaner:

  1 2 3 4 5 6 7 8 9 10 try: # ... except IsADirectoryError: print("Can't open directories") except PermissionError: print("Permission error") except UnicodeDecodeError: print("Unicode error") except Exception: print("Unknown error")

### Suppressing Exception Chaining¶

As we covered in the first post in this series, exceptions in Python 3 can be chained. when they are chained, the default traceback is updated to show this context, and earlier exceptions can be recovered from attributes of the latest.

You might also recall that it’s possible to explicitly chain exceptions with the syntax raise NewException() from exc. This sets the __cause__ attribute of the exception, as opposed to the __context__ attribute which records the original exception being handled if this one was raised within an existing exception handling block.

Well, Python 3.3 adds a new variant to this which can be used to suppress the display of any exceptions from __context__, which is raise NewException() from None. You can see an example of this behaviour below, which you can compare to the same example in the first-post:

>>> try:
...     raise Exception("one")
... except Exception as exc1:
...     try:
...         raise Exception("two")
...     except Exception as exc2:
...         raise Exception("three") from None
...
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
Exception: three

The mechanics of how this is implemented could be a little confusing because they were changed after the feature was first implemented. The original PEP 409 specified that the default value of __cause__ to be Ellipsis, which was a pretty arbitrary choice as a singleton which wasn’t an exception, so it couldn’t be confused with a real cause; and wasn’t None, so later code could detect if it had been explicitly set to None via the raise Exception() from None idiom.

It was later decided that this was overloading the purpose of __cause__ in an inelegant fashion, however, so PEP 415 was implemented which made no change to the language features introduced by PEP 409, but changed the implementation. The rather hacky use of Ellipsis was removed and a new __suppress_context__ attribute was added. The semantics are that whenever __cause__ is set (typically with raise X from Y), __suppress_context__ is flipped to true. This applies when you set __cause__ to another exception, in which case the presumption is that it’s more useful to show than __context__ since it’s by explicit programmer choice; or using the raise X from None idiom, which is just the language syntax for setting __suppress_context__ without changing __cause__. Note that regardless of the value of __suppress_context__, the contents of the __context__ attribute are still available, and any code you write in your own exception handler is, of course, not obliged to respect __suppress_context__.

I must admit, I’m struggling to think of cases where the detail of that change would make a big difference to code your write. However, I’ve learned over the years that exception handling is one of those areas of the code you tend to test less thoroughly, and those areas are exactly where it’s helpful to have a knowledge of the details since it’s that much more likely you’ll find bugs here by code inspection rather than testing.

### Introspection Improvements¶

Since time immemorial functions and classes have had a __name__ attribute. Well, it now has a little baby sibling, the __qualname__ attribute (PEP 3155) which indicates the full “path” of definition of this object, including any containing namespaces. The string represetation has also been updated to use this new, longer, specification. The semantics are mostly fairly self-explanatory, I think, so probably best illustrated with an example:

>>> class One:
...     class Two:
...         def method(self):
...             def inner():
...                 pass
...             return inner
...
>>> One.__name__, One.__qualname__
('One', 'One')
>>> One.Two.__name__, One.Two.__qualname__
('Two', 'One.Two')
>>> One.Two.method.__name__, One.Two.method.__qualname__
('method', 'One.Two.method')
>>> inner = One.Two().method()
>>> inner.__name__, inner.__qualname__
('inner', 'One.Two.method.<locals>.inner')
>>> str(inner)
'<function One.Two.method.<locals>.inner at 0x10467b170>'

Also, there’s a new inspect.signature() function for introspection of callables (PEP 362). This returns a inspect.Signature instance which references other classes such as inspect.Parameter and allows the siganture of callables to be easily introspected in code. Again, an example is probably most helpful here to give you just a flavour of what’s exposed:

>>> def myfunction(one: int, two: str = "hello", *args: str, keyword: int = None):
...     print(one, two, args, keyword)
...
>>> myfunction(123, "monty", "python", "circus")
123 monty ('python', 'circus') None
>>> inspect.signature(myfunction)
<Signature (one: int, two: str = 'hello', *args: str, keyword: int = None)>
>>> inspect.signature(myfunction).parameters["keyword"]
<Parameter "keyword: int = None">
>>> inspect.signature(myfunction).parameters["keyword"].annotation
<class 'int'>
>>> repr(inspect.signature(myfunction).parameters["keyword"].default)
'None'
>>> print("\n".join(": ".join((name, repr(param._kind)))
for name, param in inspect.signature(myfunction).parameters.items()))
one: <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>
two: <_ParameterKind.POSITIONAL_OR_KEYWORD: 1>
args: <_ParameterKind.VAR_POSITIONAL: 2>
keyword: <_ParameterKind.KEYWORD_ONLY: 3>

Finally, there’s also a new function inspect.getclosurevars() which reports the names bound in a particular function:

>>> import inspect
>>> xxx = 999
>>> def outer():
...     aaa = 100
...     def middle():
...         bbb = 200
...         def inner():
...             ccc = 300
...             return aaa + bbb + ccc + xxx
...         return inner
...     return middle()
...
>>> inspect.getclosurevars(outer())
ClosureVars(nonlocals={'aaa': 100, 'bbb': 200}, globals={'xxx': 999}, builtins={}, unbound=set())

In a similar vein there’s also inspect.getgeneratorlocals() which dumps the current internal state of a generator. This could be very useful for diagnosing bugs in the context of the caller, particularly if you don’t own the code implementing the generator and so can’t easily add logging statements or similar:

>>> def generator(maxvalue):
...     cumulative = 0
...     for i in range(maxvalue):
...         cumulative += i
...         yield cumulative
...
>>> instance = generator(10)
>>> next(instance)
0
>>> next(instance)
1
>>> next(instance)
3
>>> next(instance)
6
>>> inspect.getgeneratorlocals(instance)
{'maxvalue': 10, 'cumulative': 6, 'i': 3}

### faulthandler Module¶

There’s a new module in Python 3.3 called faulthandler which is used to show a Python traceback on an event like a segmentation fault. This could be very useful when developing or using C extension modules which often fail in a crash, making it very hard to tell where the problem actually occurred. Of course, you can fire up a debugger and figure out the line of code if it’s your module, but if it’s someone else’s at least this will help you figure out whether the error lies in your code or not.

You can enable this support at runtime with faulthandler.enable(), or you can pass -X faulthandler to the interpreter on the command-line, or set the PYTHONFAULTHANDLER environment variable. Note that this will install signal handlers for SIGSEGV, SIGFPE, SIGABRT, SIGBUS, and SIGILL — if you’re using your own signal handlers for any of these, you’ll probably want to call faulthandler.enable() first and then make sure you chain into the earlier handler from your own.

Here’s an example of it working — for the avoidance of doubt, I triggered the handler here myself by manually sending SIGSEGV to the process:

>>> import faulthandler
>>> import time
>>> faulthandler.enable()
>>>
>>> def innerfunc():
...     time.sleep(300)
...
>>> def outerfunc():
...     innerfunc()
...
>>> outerfunc()
Fatal Python error: Segmentation fault

Current thread 0x000000011966bdc0 (most recent call first):
File "<stdin>", line 2 in innerfunc
File "<stdin>", line 2 in outerfunc
File "<stdin>", line 1 in <module>
[1]    16338 segmentation fault  python3

### Module Tracing Callbacks¶

There are a couple of modules which have added the ability to register callbacks for tracing purposes.

The gc module now provides an attribute callbacks which is a list of functions which will be called before and after each garbage collection pass. Each one has two parameters passed, the first is either "start" or "stop" to indicate whether this is before or after the collection pass, and the second is a dict providing details of the results.

>>> import gc
>>> def func(*args):
...     print("GC" + repr(args))
...
>>> gc.callbacks.append(func)
>>> class MyClass:
...     def __init__(self, arg):
...         self.arg = arg
...     def __del__(self):
...         pass
...
>>> x = MyClass(None)
>>> y = MyClass(x)
>>> z = MyClass(y)
>>> x.arg = z
>>> del x, y, z
>>> gc.collect()
GC('start', {'generation': 2, 'collected': 0, 'uncollectable': 0})
GC('stop', {'generation': 2, 'collected': 6, 'uncollectable': 0})
6

The sqlite3.Connection class has a method set_trace_callback() which can be used to register a callback function which will be called for every SQL statement that’s run by the backend, and it’s passed the statement as a string. Note this doesn’t just include statements passed to the execute() method of a cursor, but may include statements that the Python module itself runs, e.g. for transaction management.

## Unicode Changes¶

With apologies to those already familiar with Unicode, a brief history lesson: Unicode was originally conceived as a 16-bit character set, which was thought to be sufficient to encode all languages in active use around the world. In 1996, however, the Unicode 2.0 standard expanded this to add 16 additional 16-bit “planes” to the set, to include scope for all characters ever used by any culture in history, plus other assorted symbols. This made it effectively a 21-bit character set3. The inital 16-bit set became the Basic Multilingual Plane (BMP), and the next two planes the Supplementary Multilingual Plane and Supplementary Ideographic Plane respectively.

OK, Unicode history lesson over. So what’s this got to do with Python? To understand that we need a brief Python history lesson. Python originally used 16-bit values for Unicode characters (i.e. UCS-2 encoding), which meant that it only suppored characters in the BMP. In Python 2.2 support for “wide” builds was added, so by adding a particular configure flag when compiling the interpreter, it could be built to use UCS-4 instead. This had the advantage of allowing the full range of all Unicode planes, but at the expense of using 4 bytes for every character. Since most distributions would use the wide build, because they had to assume full Unicode support was necessary, this meant in Python 2.x unicode objects consisting primarily of Latin-1 were four times larger than they needed to be.

This has been the case until Python 3.3, where the implementation of PEP 393 means that the concepts of narrow and wide builds has been removed and everyone can now take advantage of the ability to access all Unicode characters. This is done by deciding whether to use 1-, 2- or 4-byte characters at runtime based on the highest ordinal codepoint used in the string. So, pure ASCII or Latin-1 strings use 1-byte characters, strings composed entirely from within the BMP use 2-byte characters and if any other planes are used then 4-byte characters are used.

In the example below you can see this illustrated.

>>> # Standard ASCII has 1 byte per character plus 49 bytes overhead.
>>> sys.getsizeof("x" * 99)
148
>>> # Each new ASCII character adds 1 byte.
>>> sys.getsizeof("x" * 99 + "x")
149
>>> # Adding one BMP character expands the size of every character to
>>> # 2 bytes, plus 74 bytes overhead.
>>> sys.getsizeof("x" * 99 + "\N{bullet}")
274
>>> sys.getsizeof("x" * 99 + "\N{bullet}" + "x")
276
>>> # Moving beyond BMP expands the size of every character to 4 bytes,
>>> # plus 76 bytes overhead.
>>> sys.getsizeof("x" * 99 + "\N{taxi}")
476
>>> sys.getsizeof("x" * 99 + "\N{taxi}" + "x")
480

This basically offers the best of both worlds on the Python side. As well as reducing memory usage, this should also improve cache efficency by putting values closed together in memory. In case you’re wondering about the value of this, it’s important to remember that part of Supplementary Multilingual Plane is a funny little block called “Emoticons”, and we all know you’re not a proper application without putting "\N{face screaming in fear}" in a few critical error logs here and there. Just be aware that you may be quadrulpling the size of the string in memory by doing so.

On another Unicode related note, support for aliases has been added to the \N{...} escape sequences. Some of these are abbreviations, such as \N{SHY} for \N{SOFT HYPHEN}, and some of them are previously used incorrect names for backwards compatibility where corrections have been made to the standard. In addition these aliases are also supported in unicodedata.lookup(), and this additionally supports pre-defined sequences as well. An example of a sequence would be LATIN SMALL LETTER M WITH TILDE which is equivalent to "m\N{COMBINING TILDE}". Here are some more examples:

>>> import unicodedata
>>> "\N{NBSP}" == "\N{NO-BREAK SPACE}" == "\u00A0"
True
>>> "\N{LATIN SMALL LETTER GHA}" == "\N{LATIN SMALL LETTER OI}"
True
>>> (unicodedata.lookup("LATIN CAPITAL LETTER A WITH MACRON AND GRAVE")
... == "\N{LATIN CAPITAL LETTER A WITH MACRON}\N{COMBINING GRAVE ACCENT}")
True

## Conclusions¶

That’s it for this post, but we’re not done with Python 3.3 yet! Check out the following article for my tour of the remaining changes in this release, as well as some thoughts on the entire release.

1. As an unrelated aside, a few months ago (at time of writing!) Ian Bicking wrote a review of his main projects which makes for some interesting reading.

2. And for some people a production release tool as well, although personally I think a slightly cleaner wrapper like shrinkwrap makes for a more supportable option.

3. $2^{16} \times 17 \approx 2^{21}$

4. The ones named of the form __xxx__()

This is part 4 of the “Python 2to3” series of posts:

6 Mar 2021 at 11:11PM in Software
｜   ｜
Photo by David Clode on Unsplash


text:
# Simple question about circulation integral

1. Apr 13, 2010

### nonequilibrium

Hello. I'm new to vector calculus and I had a question about the following integral:

$$\int_{C} x dy$$ please note that this is a circulation (I didn't know the tex-code for the little circle sign on the integral)

They calculated this integral (for a specific curve) with the use of a line integral of the tangential component of F (i.e. line integral of a vector field).

But I was wondering, can this be calculated with a line integral of a scalar field? For example if C is the circle with center the origin and radius 1. I suppose for being able to do it with a scalar field, you'd then have to find a parametrization so that ds = x(t) dy(t) right? Is this doable?

(The reason I ask it is not for practical use, but to understand the theory more -- why this can't be done with a scalar field, while it looks so easy)

2. Apr 13, 2010

### elibj123

No reason it can't be done by a scalar field integration.
A usual basic integration of x as a function of y will also suffice ( this will of course require you to break C into curves which are functions and not to forget the direction of integration)

Otherwise there is no reason not to parametrize the curve with x(t) and y(t) and do the integration in terms of t.

3. Apr 13, 2010

Thank you!

format: plain


text:
### Just hanging around Koala Gardens

2012 video Some of the earliest Koala Gardens video - watching to the end is worthwhile as you can see the area first planted that is now a popular area of the property where we most often see Enigma and Stevie in particular, though we also see Bullet, Jordan, and Legion here and this was the first part of the property where Maxine was every seen. I am unable to identify who this koala is as I can't see the nose clearly enough - this was taken before I learned about nose pattern recognition and I had a very old camera.


text:
# Frame

class compas.geometry.Frame(point, xaxis, yaxis, **kwargs)[source]

A frame is defined by a base point and two orthonormal base vectors.

Parameters
• point (point) – The origin of the frame.

• xaxis (vector) – The x-axis of the frame.

• yaxis (vector) – The y-axis of the frame.

Attributes

Notes

All input vectors are orthonormalized when creating a frame, with the first vector as starting point.

Examples

>>> from compas.geometry import Point
>>> from compas.geometry import Vector
>>> f = Frame([0, 0, 0], [1, 0, 0], [0, 1, 0])
>>> f = Frame(Point(0, 0, 0), Vector(1, 0, 0), Vector(0, 1, 0))

Methods

 copy([cls]) Make an independent copy of the data object. euler_angles([static, axes]) The Euler angles from the rotation given by the frame. from_axis_angle_vector(axis_angle_vector[, …]) Construct a frame from an axis-angle vector representing the rotation. from_data(data) Construct a frame from its data representation. from_euler_angles(euler_angles[, static, …]) Construct a frame from a rotation represented by Euler angles. from_json(filepath) Construct an object from serialized data contained in a JSON file. from_jsonstring(string) Construct an object from serialized data contained in a JSON string. from_list(values) Construct a frame from a list of 12 or 16 float values. from_matrix(matrix) Construct a frame from a matrix. from_plane(plane) Constructs a frame from a plane. from_points(point, point_xaxis, point_xyplane) Constructs a frame from 3 points. from_quaternion(quaternion[, point]) Construct a frame from a rotation represented by quaternion coefficients. from_rotation(rotation[, point]) Constructs a frame from a Rotation. from_transformation(transformation) Constructs a frame from a Transformation. local_to_local_coordinates(frame1, frame2, …) Returns the object’s coordinates in frame1 in the local coordinates of frame2. Convert an object to its native data representation. to_json(filepath[, pretty]) Serialize the data representation of an object to a JSON file. to_jsonstring([pretty]) Serialize the data representation of an object to a JSON string. to_local_coordinates(object_in_wcf) Returns the object’s coordinates in the local coordinate system of the frame. to_world_coordinates(object_in_lcf) Returns the object’s coordinates in the global coordinate frame. Transform the frame. transformed(transformation) Returns a transformed copy of this primitive. Validate the object’s data against its data schema (self.DATASCHEMA). Validate the object’s data against its json schema (self.JSONSCHEMA). Construct the world XY frame. Construct the world YZ frame. Construct the world ZX frame.


text:
# finance

Doublewide dealers has an ROA of 10%, 2% profit margin and an ROE of 15%. What is its total asset turnover and multiplier? Please write out the problem so I can observe.


text:
# Orbital velocity

I don't know how to answer this question without a given altitude, but since one isn't given then I probably don't need one. Any ideas?

Determine the minimum velocity an Earth satellite must have in order to purse a stable orbit without falling to the ground.

would the period of the satellite be equal to the period of the Earth? If so it would be 24 hours or 86400 seconds (SI units) and how would that be incorporated into the problem?

I know the velocity has to be less than 11 km/sec (escape velocity).

In order to have a stable orbit, the centripetal force of the satelite must equal to the Gravitational force.
GMm/r^2=mv^2/r
For a satelite orbiting close to the earth, its radius of orbit is approximately equal to the radius of earth.
You can find v then.

tony873004
Gold Member
This question could be phrased better. You're right, you need to know the altitude. You also need to know velocity with respect to what?

A geosynchronous satellite has a velocity of 0 with respect to the ground. The distance between your house and the satellite that feeds you TV is constant, and since average velocity = delta distance/ time, and delta distance is 0, your average velocity is 0.

But orbital velocity is different. You use circumference of the orbit / time to get orbital velocity of a circular orbit. So what is the circumference of the orbit? It depends on the altitude.

The Moon has an orbital velocity of about 1 km/s. Even if you cut it down to 0.5 km/s, it would still be in a stable, but very elliptical orbit.

The Moon is near the Earth's stability radius, which is roughly defined as 1/3 the radius of the Hill Sphere. So if you compute the orbital velocity at apogee of an object whose apogee is around 400,000 km and whose perigee is around 6478 kilometers (radius of Earth + 100 km altitude), that could be the answer. Or, like you said, 0 could be the answer too.

Is there another way to answer this question with the information given in the question and any assumptions that can be made from it?

tony873004


text:
Difference between revisions of "2020 AMC 12B Problems/Problem 22"

Problem 22

What is the maximum value of $\frac{(2^t-3t)t}{4^t}$ for real values of $t?$

$\textbf{(A)}\ \frac{1}{16} \qquad\textbf{(B)}\ \frac{1}{15} \qquad\textbf{(C)}\ \frac{1}{12} \qquad\textbf{(D)}\ \frac{1}{10} \qquad\textbf{(E)}\ \frac{1}{9}$

Solution 1

We proceed by using AM-GM. We get $\frac{(2^t-3t) + 3t}{2}$ $\ge \sqrt{(2^t-3t)(3t)}$. Thus, squaring gives us that $4^{t-1} \ge (2^t-3t)(3t)$. Rembering what we want to find(divide by $4^t$), we get the maximal values as $\frac{1}{12}$, and we are done.

Solution 2

Set $u = t2^{-t}$. Then the expression in the problem can be written as $$R = - 3t^24^{-t} + t2^{-t}= - 3u^2 + u = - 3 (u - 1/6)^2 + \frac{1}{12} \le \frac{1}{12} .$$ It is easy to see that $u =\frac{1}{6}$ is attained for some value of $t$ between $t = 0$ and $t = 1$, thus the maximal value of $R$ is $\textbf{(C)}\ \frac{1}{12}$.

Solution 3 (Calculus Needed)

We want to maximize $f(t) = \frac{(2^t-3t)t}{4^t} = \frac{t\cdot 2^t-3t^2}{4^t}$. We can use the first derivative test. Use quotient rule to get the following: $$\frac{(2^t + t\cdot \ln{2} \cdot 2^t - 6t)4^t - (t\cdot 2^t - 3t^2)4^t \cdot 2\ln{2}}{(4^t)^2} = 0 \implies 2^t + t\cdot \ln{2} \cdot 2^t - 6t = (t\cdot 2^t - 3t^2) 2\ln{2}$$ $$\implies 2^t + t\cdot \ln{2}\cdot 2^t - 6t = 2t\ln{2} \cdot 2^t - 6t^2 \ln{2}$$ $$\implies 2^t(1-t\cdot \ln{2}) = 6t(1 - t\cdot \ln{2}) \implies 2^t = 6t$$Therefore, we plug this back into the original equation to get $\boxed{\textbf{(C)} \frac{1}{12}}$

~awesome1st

Solution 4

First, substitute $2^t = x (\log_2{x} = t)$ so that $$\frac{(2^t-3t)t}{4^t} = \frac{x\log_2{x}-3(\log_2{x})^2}{x^2}$$

Notice that $$\frac{x\log_2{x}-3(\log_2{x})^2}{x^2} = \frac{\log_2{x}}{x}-3\Big(\frac{\log_2{x}}{x}\Big)^2.$$

When seen as a function, $\frac{\log_2{x}}{x}-3\Big(\frac{\log_2{x}}{x}\Big)^2$ is a synthesis function that has $\frac{\log_2{x}}{x}$ as its inner function.

If we substitute $\frac{\log_2{x}}{x} = p$, the given function becomes a quadratic function that has a maximum value of $\frac{1}{12}$ when $p = \frac{1}{6}$.

Now we need to check if $\frac{\log_2{x}}{x}$ can have the value of $\frac{1}{6}$ in the range of real numbers.

In the range of (positive) real numbers, function $\frac{\log_2{x}}{x}$ is a continuous function whose value gets infinitely smaller as $x$ gets closer to 0 (as $log_2{x}$ also diverges toward negative infinity in the same condition). When $x = 2$, $\frac{\log_2{x}}{x} = \frac{1}{2}$, which is larger than $\frac{1}{6}$.

Therefore, we can assume that $\frac{\log_2{x}}{x}$ equals to $\frac{1}{6}$ when $x$ is somewhere between 1 and 2 (at least), which means that the maximum value of $\frac{(2^t-3t)t}{4^t}$ is $\boxed{\textbf{(C)}\ \frac{1}{12}}$.

Solution 5

Let the maximum value of the function be $m$. Then we have $$\frac{(2^t-3t)t}{4^t} = m \implies m2^{2t} - t2^t + 3t^2 = 0.$$ Solving for $2^{t}$, we see $$2^{t} = \frac{t}{2m} \pm \frac{\sqrt{t^2 - 12mt^2}}{2m} = \frac{t}{2m} \pm \frac{t\sqrt{1 - 12m}}{2m}.$$ We see that $1 - 12m \geq 0 \implies m \leq \frac{1}{12}.$ Therefore, the answer is $\boxed{\textbf{(C)}\ \frac{1}{12}}$.

Solution 6

Set $x=2^t$, now we get $\frac{(x-3t)t}{x^{2}}$ and we want to find the maximum value of that expression. And that expression can be further simplified to $(1-\frac{3t}{x})\frac{t}{x}$, now lets set $\frac{t}{x}$ as $y$ and we get $(1-3y)y$. Expand and we get $y-3y^{2}$. We can make it simpler by rearranging and getting $-(3y^{2}-y)$, so, now we need to find the minimum value of $3y^{2}-y$ and take the negative of that and get our answer. So, we complete the square on $3y^{2}-y$ to get it as $(y\sqrt{3}-\frac{\sqrt{3}}{6})^{2}-\frac{1}{12}$. And by the trivial inequality, any real number squared is at least $0$, so, to minimize this expression, we just set the square as $0$ and you subtract $\frac{1}{12}$ from $0$ to get $-\frac{1}{12}$ as the minimum value of the expression and you take the negative of that to get $\boxed{C=\frac{1}{12}}$ as the final answer.

~ math31415926535

Video Solution

Problem starts at 2:10 in this video: https://www.youtube.com/watch?v=5HRSzpdJaX0

-MistyMathMusic


text:
Here is a visualization of several branches of the Lambert W function on the complex plane:

This function is defined implicitly as the inverse of the nonlinear transcendental equation

$W(z) eW(z) =z$

An extremely comprehensive overview of this function, including details of evaluation and applications, is available here.

Evaluation of the function is accomplished using standard inversion algorithms, such as Newton’s method, but one needs a good starting point in order to reach all branches. To find this, first take a logarithm of both sides of the defining equation:

$W(z) =logz -logW(z) ≈logz +f(z)$

The Lambert function can thus be approximated by the natural logarithm, which explains the similarity of its appearance to that function. Putting the right-hand side into the defining equation and ignoring the additive term f in comparison to the logarithm on the resulting left-hand side,

$(logz+f) zef ≈zeflogz =z f=−loglogz$

which gives the approximation

$W(z) ≈logz -loglogz$

This form can be justified by putting it into a slightly rearranged defining equation,

$W(z) =ze −W(z) ≈ze−logz +loglogz =logz$

so that the second term of the approximation allows one to recover the first term.

All that remains now is to specify the branches of the logarithms. This can be done by keeping the second outer logarithm on the principal branch and letting the index of the Lambert function set the branch of the other functions. That is,

$Wn(z) ≈logz +2πin -log(logz +2πin)$

Starting from this complex point allows one to determine the value of the Lambert function for all branches, with the exception of the principal branch W0 in the vicinity of the origin. Since the function is zero there, starting from that value reaches most of the region around the origin, apart from some instability around the negative real axis.

Here is a comparison of the approximation (in red) to the final evaluated result:

While the Lambert function is similar to the natural logarithm, the branches of its imaginary part are not equally spaced as for the latter. This can be seen by visualizing multiple branches of the imaginary part at the same time:

The Lambert function has a complex structure with respect to argument similar to that of the natural logarithm, but reaches its asymptotic coloring noticeably faster than that function.

Uploaded 2020.11.24 — Updated 2020.12.25 analyticphysics.com


text:
# Tag Info

62

The reason is because the heat loss occurs mostly in the windows and the fenestration. The idea is that you would like the incoming air to be heated up. Also, it creates an air curtain that prevents more heat from being lost through these exposed areas. Finally, it makes the temperature of the room more or less uniform. If the heaters were placed at the ...

50

Partly practical, the wall under the windows isn't useful for anything else. We had a house where the heaters were placed in the middle of the only empty walls, so nowhere you could put furniture, bookcases, etc. Before double glazing there would be a draft from the windows so the idea was to heat this incoming air by having a radiator immediately below the ...

42

Since this is a physics forum I assume the OP is interested in a quantitative answer in terms of the efficiency of the system and how it differs based on the relative positioning of heat sources and heat sinks. The math required to analyzed such a system is too much for me to manage right now, but I believe the following principles apply and are objectively ...

10

To pretty much everything you stated in your question, "no". That convection requires a medium is not the main difference, it is simply the most obvious aspect of what is a fundamentally different mechanism for transfering energy. Convection is the transfer of energy by movement of a medium, whereas radiation is the transfer of energy by, well, thermal ...

8

Convection is the collective motion of particles in a fluid and actually encompasses both diffusion and advection. Advection is the motion of particles along the bulk flow Diffusion is the net movement of particles from high concentration to low concentration We typically describe the above two using the partial differential equations: \begin{align} ...

7

Your body removes heat by coating the skin with a thin layer of moisture (sweat). As this layer evaporates, the heat of vaporization comes from you and you feel cooler. A breeze speeds the movement of the vapor away from your skin, and therefore speeds the evaporation. This is why very hot, very humid days are so oppressive.

7

As Programmer mentions, by putting the radiator in front of the area most prone to heat loss and ingress of cold air, you are effectively screening off the room from cold air. However, there is also the fact that radiators are often quite a bit hotter than other heat sources such as forced air. Therefore it makes sense to put it in the coldest part of the ...

7

As described in the other answers, putting the radiators (or hot air vents in a forced-air system) under the windows offsets the greater heat loss of the windows, but there is another reason. As room air flows over the surface of a window, it will lose heat to the window (and the outside). This can cause moisture in the air to condense out onto the window. ...

7

I will try to explain in simple words. Every body which has a temperature above 0 Kelvin gives out (ie. radiates) some heat in the form of waves. (So, even we radiate!) Of course, the amount of this radiation depends on the temperature, so the more the temperature of the body, the more heat it gives out. Now, since this heat energy travels in the form of ...

6

Convection is the movement of a fluid, typically in response to heat. Advection is the movement of some material dissolved or suspended in the fluid. So if you have pure water and you heat it you will get convection of the water. You can't have advection because there is nothing dissolved or suspended in the fluid to advect. If you have silt suspended in ...

5

By conductor of heat, do you mean that it is bad at transferring heat via conduction? Or that it is just bad at transferring heat? First, a picture of the molecular structure of an oil: Conduction Oil is a liquid. Heat transfer by conduction requires strong bonds between the molecules, so that a vibration(heat) travels down the line. With liquids, this ...

5

If you want to dry your hands completely, you need to turn them over and over anyways. But the best approach would be if you have your palms facing up/down (can't tell which of these diagrams it is). You need to maximise the surface area of the exposed part, as heat you receive will be $\propto (surface\space area)\times(time)\times\cos(angle\space ... 5 In general, yes the updrafts also occur in warm dry air, as a result of heating on the ground which produces hyrdostatic instability in the atmosphere. As the updrafts go higher, they cool adiabatically and may, if they go high enough and if there is enough moisture in the air, cool enough to condense water vapor and form clouds. However there can also be ... 5 Let's assume that the inner pots are suspended within the containing pots, so that heat can only be transferred to them through the water in the containing pot, and that they are all open above so that steam/water vapour can escape equally well from all of them. The water in the outermost pot cannot exceed the boiling point, so it can only heat the outer ... 5 This is called an air curtain or air door and it actually keeps flying insects from being able to enter the store. It also helps trap the colder air inside. Edit: see the link for how it works. 4 I have a master's degree in meteorology so I think I can clear this up for you! This is simply ground clutter. You will see this sort of thing happening on evenings where the relative humidity is very high, more so when the mixing ratio is high also. The radar beam can actually start to interact with water droplets in the air when your humidity values ... 4 KamLAND Borexino has set moderately strict limits of the total power of a central geo-reactor. See for instance Geo-neutrino: Experiments (pdf link) a talk by one of my colleagues. (Jalena notes that Borexino's limit is the strongest one going, but KamLAND was the leader for a while.) The upper extreme of these limits is less than half the total geological ... 4 I don't know a good answer to your first question (I'd be interested in a good text for that myself), but I can answer the second. It's easier to explain if we temporarily imagine$\phi$represents the concentration of some dye made up of little particles suspended in the fluid. The convective term (aka advective term) is transport of$\phi$due to the ... 3 No proposed urban rainfall effect is dominant enough to cause that picture. But limited radar range, with radars being located in larger cities would easily explain it. The urban rainfall enhancement effect would have to be pretty extreme for it to be otherwise. 3 This is covered in the standard convection-diffusion type of equation: $$\frac{\partial C}{\partial t} + \vec{u} \cdot \nabla C= D \nabla^2 C$$ Where$C$is the smoke concentration, and$D$is the diffusion coefficient of smoke. While the air may be stagnant initially, it will come to move due to buoyancy effects, thus giving some non-zero air velocity ... 3 I'm sure it depends on the mug and the temperature of the coffee, but most of the time I bet that evaporative cooling from the top is the dominant source of heat loss. That's just based on experience--like it stays hot much longer when you cover the top, and much shorter when you blow on the top. I also think that it cools at a similar rate in my ceramic mug ... 3 The molecules are all moving, quite rapidly, all the time, and constantly colliding against each other. The warmer ones are moving even more rapidly, thus "winning out" in their collisions with the cooler ones, pushing them away. (That's what lower density is.) Then if there's some gravity field pulling all of them downwards against a surface (they're not ... 3 Semi-macroscopic view: The key word for understanding this problem is buoyancy. Buoyancy is the result of different pressures. Since the warm air is less dense than the cold one, there are less hits to the (imaginary) balloon of warmer particles from inside than from outside, so there is net pressure toward inside. However, since this pressure difference ... 3 http://www.egr.msu.edu/~somerton/Nusselt/ here you can find some formulas for calculating Nusselt, Prandtl, Reynolds, Rayleigh and Grasshoff numbers. Those are important for evaluating conditions in different systems. Numbers will tell you which state of convection is around your geometry (natural, forced, laminar, turbulent, external, internal). For each ... 3 Most shopping malls have this kind of air door that blast you with high velocity air flow when you enter. As you might have noticed, shopping malls are always the cleanest places of them all. And I am not just talking about cleanliness of the floor area but the entire atmosphere in a mall. The reason they keep it clean is obvious. The method which they use ... 3 As the hot air goes up and the cold air goes down, the radiator is located where there is a better circulation, i.e. even though the window is double glazed, there will always be cold air entering the division by the material itself. So the cold will push the hot air inside the room. Another explanation can be the fact that external walls can have thermal ... 3 No, it doesn't mean that the photons don't go any further. It means that when the temperature gradient inside the star reaches a threshold, the gas becomes convectively unstable. Heat is transferred more efficiently by moving parcels of gas than by transferring photons from hotter regions to cooler regions. So, the photons continue to diffuse outwards, but ... 2 convection = diffusion + advection. That is, convection is the sum of fluid movement due to bulk transport of the media (like the water in a river flowing down a stream - advection) and the brownian/osmotic dispersion of a fluid constituent from high density to lower density regions (like a drop of ink slowly spreading out in a glass of water - diffusion). 2 The equation you state is a very general expression related to heat transfer, and basically everything goes into that constant. Convection of course is one thing, but what about radiative cooling (often important), diffusive cooling (might be important), and heat resistance, since the temperature of your object is not uniform. All these contributions can be ... 2 The rate of temperature change will be the power per unit mass times the specific heat. So if you have a certain mass of water$M$flowing per second, at a velocity$v$, losing$\Delta P$pressure per second, then work done is$v\Delta P A$and$A = \frac{M}{\rho v}$. Then with a heat capacity$c\$ (about 4.2 kJ/kg/K for water), and the relationship between ...

Only top voted, non community-wiki answers of a minimum length are eligible


text:
# Thread: Law of Sines....I think

1. ## Law of Sines....I think

Two lookout stations, which are 25 miles apart along the coast on a north-south line, spot an approaching yacht. One lookout station measures the direction to the yacht at N33* E, and the other station measures the direction of the yacht at S62* E. How far is the yacht from each lookout station? How far is the yacht from the coast?

2. Hello, suzdisp!

Did you make a sketch?

Two lookout stations, which are 25 miles apart along a north-south costline,
spot an approaching yacht.
One lookout station finds the direction to the yacht at N33°E,
and the other station finds the direction of the yacht at S62°E.

(1) How far is the yacht from each lookout station?

(2) How far is the yacht from the coast?
Code:
  -  B*
:   |  *
:   | 62° *   a
:   |        *
:   |           *
:   |              *
:  D* - - - - - - 85° *C
:   |               *
25   |             *
:   |           *
:   |         *
:   |       * b
:   |     *
:   |33°*
:   | *
-  A*

Since $\angle A = 33^o,\:\angle B = 62^o$, then: . $\angle C \:=\:180^o - 33^o - 62^o \:=\:85^o$

Law of Sines: . $\frac{a}{\sin A} \:=\:\frac{c}{\sin C} \quad\Rightarrow\quad a \:=\:\frac{c\sin A}{\sin C}$

. . $a \:=\:\frac{25\sin33^o}{\sin86^o} \;=\;13.66798666 \quad\Rightarrow\quad\boxed{ a \;\approx\;13.7\text{ miles}}$ (1)

Law of Sines: . $\frac{b}{\sin B} \:=\:\frac{c}{\sin C} \quad\Rightarrow\quad b \:=\:\frac{c\sin B}{\sin C}$

. . $b \:=\:\frac{25\sin62^o}{\sin85^o} \:=\:22.15800773 \quad\Rightarrow\quad\boxed{ b \;\approx\;22.2\text{ miles}}$ (1)

In right triangle $CDA\!:\;\;\sin33^o \:=\:\frac{CD}{b}$

Therefore: . $CD \:=\:22.2\sin33^o \:=\:12.09068658\quad\Rightarrow\quad\boxed{ CD \:\approx\:12.1\text{ miles}}$ (2)


text:
Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.

Topic: Discontinuity of a derivative function
Replies: 5   Last Post: Dec 11, 2000 5:08 AM

 Messages: [ Previous | Next ]
 Lars Olsen Posts: 18 Registered: 12/13/04
Re: Discontinuity of a derivative function
Posted: Dec 11, 2000 5:08 AM

In article <3A32A113.B17B42C7@cornell.edu>, pa44@cornell.edu wrote:

> Nir wrote:
> >
> > Is there any restriction on the "quantity" of the points of
> > discontinuity of a function which is a derivative of another function
> > ? (For example, does the set of all points of discontinuity of a
> > derivative function have to be of Lebesgue measure zero or something
> > like that ?)

>
> Although I couldn't construct one, there are functions that are
> everywhere differentiable but whose derivative is nowhere continuous.
> So I'm guessing that there are no restrictions.
>
> -Peter

Not quite true.

For a function g:R\to R let Cont(g) denote the set of continuity points of g.

A function g:R\to R that is the _pointwise_ limit of a sequence of
continuous functions is called a Baire 1 function.

The following result is a classical result (going back to Baire), cf. [K,
(24.14)]

Theorem. If f:R\to R is Baire 1, then Cont(f) is dense in R (in fact,
Cont(f) is a comeager G_delta set).

Let E be any non-dense G_delta subset of R (e.g. E could be the empty
set), then (since a derivative is Baire 1) the above Theorem implies that
there is no differentiable function f:R\to R such that

Cont(f') = E.

In particular, there is no differentiable function f:R\to R such that

Cont(f') = the empty set.

In fact, the following more general result, due to Zahorski [Z], holds.

Theorem. Let M be a subset of R. Then the following are equivalent:
(1) There exists a continuous function f:R\to R such that

M={x|f is differentiable at x}

(2) There exist a G_delta set A and a F_sigma_delta set B with:

Lebesgue measure of (B intersection [a,b]) = b-a for all a<b

such that:

M = (A intersection B)

For a nice survey of these and related topics see [B].

References

[B] Bruckner, Andrew Differentiation of real functions. Second edition. CRM
Monograph Series, 5. American Mathematical Society, Providence, RI, 1994

[K] Kechris, Classical Descriptive Settheory, Springer Verlag.

[KL] Ki & Linton. Normal numbers and subsets of $\bold N$ with given densities.
Fund. Math. 144 (1994), no. 2, 163--179]

[Z] Zahorski, Z. Sur la premiÃÂÃÂ¨re dÃÂÃÂ©rivÃÂÃÂ©e. Trans. Amer. Math. Soc. 69,
(1950). 1--54.

Best regards Lars

Date Subject Author
12/9/00 Nir
12/9/00 Paolo
12/9/00 Peter Ammon
12/9/00 G. A. Edgar
12/10/00 David C. Ullrich
12/11/00 Lars Olsen


text:
# Impulse response when input to a system is differentiated, and its applicability to find response to general inputs

I will first give a short explanation of what I am asking, and then give a more comprehensive context.

If we have a LTI dynamic system acted upon by inputs $$y(t)$$ and producing outputs $$x(t)$$,

,

we know that we can calculate a response to any arbitrary input if we know the system's unit impulse response $$w(t)$$, i.e. its response to a unit impulse input, or Dirac function, $$y(t)=\delta(t)$$. But what if the system is such that its inputs are differentiated, so that the impulse we feed into it gets differentiated as well? Would the corresponding response still be considered impulse response and be applicable for obtaining solutions to arbitrary inputs?

To further explain let's look at an example. Say we model a mechanical system and obtain the following LTI ordinary differential equation:

$$m\ddot{x} + b\dot{x} + cx = y$$.

To get $$x(t)=w(t)$$, we would set $$y(t) = \delta(t)$$ and solve either directly and get $$w(t)$$ or use Laplace transform and get $$W(s)$$. We would then use $$w(t)$$ or $$W(s)$$ to calculate the output to arbitrary input $$y(t)$$, either directly using convolution or using mutiplication in s-domain (and then inverse Laplace transform of $$X(s)$$ if we really need $$x(t)$$, which we often don't):

$$x(t) = w(t)*y(t)$$

$$X(s) = W(s)Y(s)$$.

$$W(s)$$ is the transfer function of the system (not proving this here, just stating), so let's focus on the second option ($$s$$-domain) because of the advantages of Laplace transform approach, such as algebraic simplicity and gaining insight about system response from $$W(s)$$ alone.

Now, what if our system was just a little different, like below (this is not contrived, for instance it corresponds to a simple automobile suspension model)?

$$m\ddot{x} + b\dot{x} + cx = b\dot{y}$$

The input gets differentiated! If we now set input $$y(t) = \delta(t)$$, it will act on the system differentiated. So although unit impulse is the input to the system, when we compare what we get on right hand sides of this and the first ODE, it does not quite seem straigtforward to call the response impulse response. However, there is no formal reason not to either. Let's make this more general to illustrate.

Using polynomial differential operators $$P(D)$$ and $$Q(D)$$, a general form of a LTI ODE is:

$$P(D)x = Q(D)y$$

In both above examples, $$P(D)=mD^2 + bD + c$$, while $$Q(D) = 1$$ in the first example and $$Q(D) = bD$$ in the second example. You can see that $$D$$, $$D^2$$ and so on stand for differentiation - if we bear this in mind we can formally multiply $$x$$ and $$y$$ by polynomials of $$D$$, $$P(D)$$ and $$Q(D)$$, and use this simple and convenient notation to write any LTI ODE. So if we have a delta function as input in a general LTI ODE, we can write this as follows:

$$P(D)x = Q(D)y, y = \delta(t)$$

Usually when impulse response is considered, only the case $$P(D)x=y$$ is explicitly considered, i.e. it is assumed $$Q(D)=1$$ so we have strictly $$\delta(t)$$ on the right hand side. However I see no formal or practical reason why we wouldn't admit the general form of the ODE as above and still draw exactly the same conclusions about solving ODEs with arbitrary inputs $$f(t)$$ using the impulse response $$w(t)$$. Specifically, I think we could say that for

$$P(D)x = Q(D)f(t), f(t) \text{arbitrary, rest I.C.},$$

the solution is given by a convolution

$$x(t)=w(t)*f(t)$$,

which can also be calculated as its Laplace transform

$$X(s)=W(s)F(s), W(s)=\frac {Q(s)}{P(s)}$$,

where $$W(s)$$ is the transfer function, i.e. the Laplace transform of the unit impulse response $$w(t)$$ of the given ODE (where $$Q(D)$$ actually contains some derivatives). Is this correct?

• the W is modified to include the differential. – Stanley Pawlukiewicz Sep 22 '18 at 18:38

I think your question can be reduced to the simpler question:

Is a differentiator fully characterized by its transfer function?

Is a differentiator a linear time-invariant (LTI) system?

The answer to the latter question is easily shown to be in the affirmative.

Given a system represented by an LTI ODE with rest (zero) initial conditions, of the form:

$$P(D)x=f(t), \text{rest I.C.,}$$

it is a fact that we can calculate the response to arbitrary input $$f(t)$$ if we know the impulse response $$w(t)$$, i.e. the solution $$x = w(t)$$ to :

$$P(D)x=\delta(t) \text{, rest I.C.,}$$

as the following convolution or multiplication in the s-domain:

$$x(t) = w(t)*f(t)$$

$$X(s) = W(s)*F(s)$$.

The proof rests on the fact that the system is indeed linear, time invariant, in other words that a linear combination of several time-shifted inputs leads to the same linear combination of equally time-shifted outputs to those inputs when they act alone and without time shift. Therefore, to prove that this also holds for a general LTI ODE:

$$P(D)x=Q(D)f(t), \text{rest I.C.,}$$

one must only prove that this is also a LTI system. We know that the left hand side is LTI, so we only need to prove that the right hand side is as well, i.e. that $$Q(D)$$ acting on a linear combination of several time shifted functions gives the same linear combination of equally time-shifted functions that are each individually acted on by $$Q(D)$$. Since the right hand side is of the exact same form as the left one, it obviously also is LTI. Therefore, the above methods for computing outputs to arbitrary inputs must also be valid. The output to impulse input $$f(t) = \delta(t)$$ can indeed be considered as the impuse response $$w(t)$$ and used in the convolution or transformed to obtain the transfer function $$W(s)$$.

This completes the proof, but I will add a short explicit demonstration that $$Q(D)f(t)$$ is linear, time invariant.

Proof of linearity of $$Q(D)f(t)$$

Linearity means that if the input is a linear combination of two inputs $$y_1$$ and $$y_2$$, i.e. $$f(t) = ay_1+by_2$$, after it gets operated on (differentiated) by $$Q(D)$$ it must become the same combination of individually differentiated inputs, i.e. $$aQ(D)y_1+bQ(D)y_2$$.

Since $$Q(D)$$ consists only of a lot of derivatives, a linear combination of these inputs will indeed give:

$$Q(D)(ay_1+by_2)=aQ(D)y_1+bQ(D)y_2$$

So indeed $$Q(D)f(t)$$ is linear.

Proof of time invariance of $$Q(D)f(t)$$

Time invariance means that if the input is first time shifted by $$\tau$$ to be $$f(t-\tau)$$ and only then gets operated on (differentiated) by $$Q(D)$$, it must give the same solution as when the non-shifted input $$f(t)$$ is first differentiated, and only then the result time shifted by $$\tau$$.

This is impractical to prove using $$Q(D)$$ notation, so lets show it for individual terms $$a_kD^k$$ of $$Q(D) = a_nD^n + a_{n-1}D^{n-1} + ... + a_1D + a_0$$, where the $$a_k$$s are constants and $$D^k$$ is $$\frac{d^k}{dt^k}$$.

Use substitution:

$$f(t-\tau) = f(t^*), t^* = t-\tau$$

By chain rule:

$$\frac{d}{dt}f(t^*) = \frac{df(t^*)}{dt^*}\frac{dt^*}{dt} = \frac{df(t^*)}{dt^*}\frac{d}{dt}(t-\tau) = \frac{d}{dt^*}f(t^*)$$

Using alternative notation for leftmost and rightmost expressions above makes the order of operations clearer:

$$[f(t^*)]' = f'(t^*)$$

On the left, we first shift then differentiate, while on the right, we first differentiate then shift. The results are equal, so first order differentiation is time invariant. This easily propagates to higher derivatives, i.e. higher terms $$a_kD^k$$ of $$Q(D)$$, thus $$Q(D)f(t)$$ is indeed time invariant.


text:
# Greek Capital Letter Upsilon

Υ
Symbol Format Data
Υ Code Point
U+03A5
TeX
\Upsilon
SVG

## Usage

The capital Greek letter (capital upsilon) is visually very similar to the upper-case Latin letter Y. For that reason, refer to the usage of Capital T for how the symbol appears in math.

## Related

The Greek letter upsilon (υ).


text:
Avoid accidental library functions

Have you ever seen a function like this?

def getResultsFromFooService(param1: str, param2: str, param3: str = "param3Default",\
sort: bool = False, raiseException: bool = False, version: int = 1) -> List[str]:
"""Gets the results from the Foo Service and returns it as a list of strings.

This function works with both version 1 and version 2 of the Foo Service API.

Args:
param1: The first API parameter
param2: The second API parameter
param3: The third API parameter; ONLY applies for version 2 of the API!
sort: Whether to sort the results by their timestamp
raiseException: Whether to raise an exception if an error is encountered; if False, then an empty List would be returned instead.
version: The version of the Foo API to use. Currently supports either 1 or 2.

Returns:
List[str]: A list of strings representing the results
"""
...

This function suffers from trying to do too much, and trying to be too flexible in how it does it. It has multiple parameters, not all of which may be used (param3 only applies if you use version=2), and the flexibility it offers via these parameters creates confusion as to how it should be called: Should you suppress exceptions or not? Why would I want to sort the results? Can I sort by something other than timestamp?

I call these accidental library functions. They are functions that were extended piecemeal over time to become a piece of common code, but probably should have never been a common function in the first place.

Frequently, such accidental library functions are difficult to call properly, and become a source of bugs, because they are difficult to understand. They are also not easy to change, as they are called from multiple places in different ways, so it’s not straightforward to see how a change might break the calling code.

How do these happen?

The unintended consequences of reducing code duplication

We are all taught early on in our careers that code duplication is a Bad Thing: “Thou shalt not duplicate code, lest thy violate the principle of Do not Repeat Yourself". It’s obvious what the downsides of code duplication are, so I won’t go over them.

However, I am going to posit that eliminating code duplication by making common functions is not necessary a net positive, and is in fact a trade-off. Bear with me, since I know I’ve violated the sacred orthodoxy.

In my experience, accidental library functions (like the one above) usually come from a dogmatic approach that treats code duplication as a “must avoid” without regard to the overall flow of the code, and how it might evolve. Let me give you an example.

Suppose we have two flows, labeled X and Y here. They could represent different API endpoints. For example, X could be the endpoint where you get widgets of type X, and Y could be the endpoint where you get widgets of type Y. Let us also assume that they each have a section of code that is identical. If we want to ensure there is no code duplication, we would refactor that common code into a function (let’s call it A), and now the flows look like this:

Everything is fine with this, and at this point, A is truly a common piece of code.

Now suppose a change is made in Flow X that requires changes in A to accommodate this. At this point, you have two options:

1. Modify A to support both the new X and unchanged Y flows. This will likely require passing in a flag and branching within A, hence A is modified to A’
2. Break out A into A1 (the original, serving Y) and A2 (serving X)

If Flow X is going to be changing fast, I am going to posit that (2) is better because it allows you to change A2 without having to worry about affecting anything other than Flow X. However, chances are that (2) won’t be taken because it takes extra effort compared to (1), and also knowing whether Flow X is going to be changing fast is often subjective. Hence, for reasons of inertia option (1) is almost always taken, and our system becomes something like this:

Now let’s say we have to add Flow Z, and A’ almost does what it needs, but not quite - so we add another flag to A’ and it becomes A”, with even more branching. Repeat this process a few more times, and soon we have an accidental library function.

In this accidental library function, there is actually very little commonality, and instead we just have a single function that is trying to do too much and is essentially handling multiple use cases individually with if/else branches.

The root of the problem here is that when we designed Flow X and Y, we decided to reduce code duplication and create a single function A. This single function became the default position in the code base, and led to subsequent changes trying to preserve its supposed commonality. This resulted in unrelated flows being coupled together through the use of the wrong abstraction.

When you decide to reduce code duplication by refactoring things out into a common function that is called by two or more flows, you are making several assumptions, whether you realize it or not.

The assumptions that you are making are:

1. The common function will always be used in the same way by all the flows.
2. If you need to make a change to this common function, it will apply to all flows.
3. If you need to make a change to only one of the flows, you won’t need to change the common function. (This follows from (2))

If any of these assumptions are violated, the benefits you attempted to get by reducing code duplication may be outweighed by the extra maintenance you will incur from trying to make your common code work for new use cases.

Whether these assumptions are correct depends on a variety of factors, and it doesn’t always come out in favour of reducing code duplication. Some factors that I’ve observed which contribute to whether the assumption is correct or not are:

• If you expect the flows to change in different ways and not in lock-step, it’s likely your common function will not be common after some time.
This is especially true if one of the flows is not being actively developed (maintenance mode) and the other is being rapidly iterated on.
• How long is the common function? How much logic is encapsulated there?
The longer the function, the more specific it is, and thus the less likely it is to survive being common if the flows change.
• How many flows are calling this common function? If it’s only two, chances are it’s not truly common but rather just coincidental.
Attempting to produce a common function on the basis of only two examples is almost certainly overfitting and will result in a “common” function that eventually itself needs refactoring. Instead, you should follow the Rule of Three, which roughly states that two duplications are OK, but when you have three, it’s probably time to refactor.

These are some things to think about before you decide on whether to refactor and reduce code duplication.

Library functions require a higher standard of care

Another nice way to avoid accidental library functions is to think about what an ideal library function should be. An ideal library function is one that can be reused not just across the current code, but is also likely to be useful for future use cases. Obviously this is harder than it sounds, so let’s go through some examples.

An example of an ideal library function might be a function that returns the Top-K values from a list. This function would take at most three parameters: A list, a value for K, and perhaps a function that defines how to order the items in the list.

We can think of some aspects of what makes a good library function, based on this example:

1. It does one thing
2. It doesn’t have a huge parameter list, so it is straightforward to use
3. Once written, it’s unlikely that you’ll have to change it (unless there was a bug)

By contrast, the example I presented at the beginning violates all three of the points above. I’ve found that point (3) above is the most salient; if you find yourself frequently changing a piece of “common” code, it probably shouldn’t be common!

Conclusion

I’ve harped on this topic a little excessively, but I wanted to provide a counterpoint to the default assumption that code duplication is always a bad thing. I’ve demonstrated how a knee-jerk reaction to eliminate all code duplication can result in unintended and unnecessary code coupling and complexity down the line, but this isn’t to say that the pendulum should swing all the way over to always preferring code duplication.

For example, there are some cases where code duplication is almost certainly a Bad Thing, such as wholesale copying of entire classes and packages; this should almost always be avoided.

The point here is that we shouldn’t base our decisions on rigid rules relating to code duplication. Instead, we should consider whether the abstraction being used is the correct one, after taking into account the particular situation or scenario in your application.


text:
Share

# An Electron Microscope Uses Electrons Accelerated by a Voltage of 50 kv. Determine the De-broglie Wavelength Associated with the Electrons. - Physics

#### Question

An electron microscope uses electrons accelerated by a voltage of 50 kV. Determine the de-Broglie wavelength associated with the electrons. Taking other factors, such as numerical aperture etc. to be same, how does the resolving power of an electron microscope compare with that of an optical microscope which used yellow light?

#### Solution 1

The de-Broglie wavelength of the electrons is given by:

lambda=h/(sqrt(2meV))

Here:

m =  mass of the electron = 9.1×10-31 kg

e = charge on the electron = 1.6×10-19 C

V = accelerating potential = 50 kV

h = Planck's constant = 6.626×10-34 Js

=>lambda=(6.626xx10^(-34))/sqrt(2(9.1xx10^(-31))(1.6xx10^(-19))(50xx10^3))

λ=0.0549 Å

Resolving power of a microscope, R=(2musintheta)/lambda

This formula suggests that to improve resolution, we have to use shorter wavelength and media with large indices of refraction. For an electron microscope, μ is equal to 1(vacuum).

For an electron microscope, the electrons are accelerated through a 60,000 V potential difference. Thus the wavelength of electrons is found to be

lambda=12.27/sqrtV=12.27/sqrt60000=0.05Å

As, λ is very small (approximately 10-5 times smaller) for electron microscope than an optical microscope which uses yellow light of wavelength (5700 Å to 5900 Å). Hence, the resolving power of an electron microscope is much greater than that of optical microscope.

#### Solution 2

Electrons are accelerated by a voltage, V = 50 kV = 50 × 103 V

Charge on an electron, e = 1.6 × 10−19 C

Mass of an electron, me = 9.11 × 10−31 kg

Wavelength of yellow light = 5.9 × 10−7 m

The kinetic energy of the electron is given as:

E = eV

= 1.6 × 10−19 × 50 × 103

= 8 × 10−15 J

De Broglie wavelength is given by the relation:

lambda = h/sqrt(2m_eE)

= (6.6 xx 10^(-34))/sqrt(2 xx 9.11 xx 10^(-31) xx 8 xx 10^(-15))

= 5.467 xx 10^(-12) m

This wavelength is nearly 10times less than the wavelength of yellow light.

The resolving power of a microscope is inversely proportional to the wavelength of light used. Thus, the resolving power of an electron microscope is nearly 105 times that of an optical microscope.

Is there an error in this question or solution?

#### Video TutorialsVIEW ALL [2]

Solution An Electron Microscope Uses Electrons Accelerated by a Voltage of 50 kv. Determine the De-broglie Wavelength Associated with the Electrons. Concept: Davisson-Germer Experiment.
S


text:
Mathematical function to check whether its parameter is zero or not

i need a mathematical function F which is defined as F(x) = 0 if x equal to zero and F(x) = 1 if x is not equal to zero. can F(x) be represented in the form of a single mathematical expression in terms of x?

-
Hi Anil. Welcome to stackexchange. Hope you will get an answer soon. (the guy from Vark.com) – mplungjan Feb 25 '11 at 13:41
You can write it as $1_{\mathbb R\setminus\{0\}}(x)$ but that is just a name. What do you mean with "a single mathematical expression"? – Rasmus Feb 25 '11 at 13:45
You have already defined the function. What more do you need? – Qiaochu Yuan Feb 25 '11 at 13:48
These types of questions usually arise from a limited understanding of functions. A function (in a limited point of view) is a machine which returns a number, if you supply the function a number. As an example you can define the absolute value as $|x|=\sqrt{x^2}$. Is this a better definition than $x=x$ if $x\geq 0$, and $x=-x$ is $x<0$? If you think so, you should ask yourself: how do you define the square root? – Thomas Rot Feb 25 '11 at 14:15
If you let $S$ be the set containing $0$ then $F(X)$ is often called the characteristic (or indicator) function of $\mathbb R - S$. It already is a single mathematical definition for any $x \in \mathbb R$, but maybe you are looking for a concise way to describe it? – Joshua Shane Liberman Feb 25 '11 at 14:34

Knuth suggests using the Iverson bracket notation $[x\ne0]$ for that function. You can also try $|\mbox{sgn}(x)|$. See http://en.wikipedia.org/wiki/Sign_function


text:
# Why is Frobenius norm related to the inner product of characters?

This is a continuation of my question asked here.

I am going through Normal Subgroup Reconstruction and Quantum Computation Using Group Representations. In Definition 2, the authors start with the following function.

$$f : G \to \mathbb{C}$$

Then the Fourier transform of $f$ at the irrep $\rho$ is defined as the $d_\rho \times d_\rho$ matrix:

$$\hat{f}(\rho) = \sqrt{\frac{d_\rho}{|G|}} \sum_{g \in G} f (g) \rho(g)$$

In the quantum computational settings, the authors identify the superposition $\sum_{g \in G} f_g |g\rangle$ ($|a\rangle$ is a quantum state which is the $a$-th computational basis vector), with the function $f:G\to\mathbb{C}$ defined by $f(g) = f_g$.

In this notation, $\sum_{g \in G} f(g)|g\rangle$ is mapped under the Fourier transform to $\sum_{\rho \in \hat{G}, 1\le i,j \le d_\rho} \hat{f}(\rho)_{i,j} |\rho, i, j\rangle$.

$(\rho, i, j)$ is the label of the $(\rho, i, j)$-th computational basis vector $|\rho, i, j\rangle$. $\hat{f}(\rho)_{i,j}$ is a complex number and the $(i,j)$-th element of the matrix $\hat{f}(\rho)$. $\hat{G}$ is the collection of all irreps of $G$.

Then the authors say as follows.

When the first portion of this triple is measured, we observe $\rho \in \hat{G}$ with probability

$$\sum_{1\le i,j\le d_\rho} |\hat{f}(\rho)_{i,j}|^2 = ||\hat{f}(\rho)||^2\\ = tr ((\hat{f}(\rho))^* \hat{f}(\rho))$$

Here, ($\rho, i, j$) is the triple the authors are referring to. Measuring $\rho$ means measuring the qubits which encode the label $\rho$.

I understand up to this part. Then in Section 3, right after Equation 2, the authors go on saying:

$$||\hat{f}(\rho)||^2 = ||\sqrt{\frac{d_\rho}{|G|}} \sum_{h\in H} \rho(h)||^2$$

I know that $\rho$ may not be an irrep for $H$. But, the matrix elements in $\hat{f}(\rho)$ comes from the direct sum of the matrices $\rho(h)$. I assume the previous equation works because of the Equation (2) in the paper.

I do not understand from here. The equation written by the authors is as follows:

$$||\hat{f}(\rho)||^2 = ||\sqrt{\frac{d_\rho}{|G|}} \sum_{h\in H} \rho(h)||^2\\ = \frac{d_\rho}{|G|} \frac{1}{|H|} |H|^2 \langle \chi_\rho, \chi_{1_H} \rangle_H \\= \frac{|H|}{|G|} d_\rho \langle \chi_\rho, \chi_{1_H} \rangle_H$$

Here, $\chi_{1_H}$ is the character of the trivial representation of the subgroup $H$.

My question:

Why is $||\sum_{h\in H} \rho (h)||^2 = \frac{1}{|H|} |H|^2 \langle \chi_\rho, \chi_{1_H} \rangle_H$? According to the definition of the Frobenius Norm, it should be like $||\sum_{h\in H} \rho (h)||^2 = Tr \left(\left(\sum_{h\in H} \rho (h)\right)\left(\sum_{h\in H} \rho (h)\right)^\dagger\right)$. I do not understand the following relationship.

$$Tr \left(\left(\sum_{h\in H} \rho (h)\right)\left(\sum_{h\in H} \rho (h)\right)^\dagger\right) = \frac{1}{|H|} |H|^2 \langle \chi_\rho, \chi_{1_H} \rangle_H$$

It's important that on the first page the paper states that, without loss of generality, all of their irreducible representations are unitary, so that $\rho(g)^\dagger=\rho(g)^{-1}$ for all $g\in G$.

By the way, the beginning of section $3$ is in error. The sum $\sum_{h\in H}\rho(h)$ is not a projection, because it is not normalized correctly. Instead, $|H|^{-1}\sum_{h\in H}\rho(h)$ is the projection:

$$\left(\frac{1}{|H|}\sum_{h\in H}\rho(h)\right)^2=\frac{1}{|H|^2}\sum_{h_1,h_2\in H} \rho(h_1 h_2)=\frac{1}{|H|}\sum_{h\in H}\rho(h)$$

because $h_1h_2=h$ has $|H|$ solutions $(h_1,h_2)\in H\times H$.

Next, I am not sure why the bottom of the page introduces $\sqrt{d_\rho/|G|}$. According to the definition of the Fourier transform on the previous page, one introduces this constant when transforming from an initially given function $f:G\to\mathbb{C}$ to $\widehat{f}$. However section $3$ begins by defining $\widehat{f}$ to be a certain projection operator (at least it wanted to it seems), so there's no need for that constant.

Thus, let's just talk about the projection map $\widehat{f}(\rho)=|H|^{-1}\sum_{h\in H}\rho(h)$. We have

$$\begin{array}{ll} \|\widehat{f}(\rho)\|^2 & \displaystyle =\left\|\frac{1}{|H|}\sum_{h\in H}\rho(h)\right\|^2 \\ & \displaystyle =\frac{1}{|H|^2}\mathrm{tr}\left(\sum_{h_1\in H}\rho(h_1)\right)\left(\sum_{h_2\in H}\rho(h_2)\right)^\dagger \\ & \displaystyle =\frac{1}{|H|^2}\mathrm{tr}\sum_{h_1,h_2\in H}\rho(h_1h_2^{-1}) \\ & \displaystyle =\frac{1}{|H|}\sum_{h\in H}\chi(h), \end{array}$$

again because $h_1h_2^{-1}=h$ has $|H|$ solutions $(h_1,h_2)\in H\times H$. The above is $\langle \chi,\chi_{1_H}\rangle_H$.

The inner product $\langle \chi,\psi\rangle_H=\frac{1}{|H|}\sum_{h\in H}\chi(h)\overline{\psi(h)}$ on characters can be used to sift for the multiplicities of irreps within a given rep. Suppose that $V$ is a complex representation of $H$, and that $V\cong \bigoplus_{X\in\widehat{H}}X^{\oplus m(X)}$ is $V$'s decomp into irreps $X\in\widehat{H}$ with multiplicities $m(X)$. Then for a fixed irrep $Y$, because $\hom$ distributes over $\oplus$, we have

$$\begin{array}{ll} \hom_H(V,Y) & \displaystyle =\hom_H\left(\sum_{X\in\widehat{H}} X^{\oplus m(X)},Y\right) \\ & \displaystyle \cong\bigoplus_{X\in\widehat{H}} \hom_H(X,Y)^{\oplus m(X)} \\ & \displaystyle \cong \mathbb{C}^{\oplus m(Y)} \end{array}$$

This follows since, by Schur's lemma, $\hom_H(X,Y)\cong\mathbb{C}$ if $X=Y$ and is $0$ otherwise (when $X,Y$ are irreps of $H$). On the other hand, $\hom(V,Y)$, as a representation of $H$, is isomorphic to the tensor product $V^*\otimes Y$ (a special case of tensor-hom adjunction, the linearization of currying), and so $\dim\hom_H(V,Y)\cong\dim(V^*\otimes Y)^H$. But if $Z$ is an $H$-rep, the dimension of $Z^H$ is just the trace of any projection operator $Z\to Z^H$, which we know $|H|^{-1}\sum_{h\in H}\rho_Z(h)$ is, so applying this with $Z=V^*\otimes Y$ yields $m(Y)=|H|^{-1}\sum_{h\in H}\overline{\chi_V(h)}\chi_Y(h)=\langle \chi_Y,\chi_V\rangle$.

For example, suppose $H=\langle\omega\rangle=\{1,\omega,\omega^2\}$ is the group of $3$rd roots of unity. If we write

$$\sum_{h_2\in H}\rho(h_2)=\rho(1)+\rho(\omega)+\rho(\omega^2)$$

and set $h_1=\omega$, then we have

$$\sum_{h_2\in H}\rho(h_1h_2)=\rho(\omega)+\rho(\omega^2)+\rho(1).$$

It's the same sum, only permuted. Therefore,

$$\sum_{h_1\in H}\left(\sum_{h_2\in H}\rho(h_1h_2)\right)=\left(\color{Purple}{\sum_{h_2\in H}\rho(h_2)}\right)+\left(\color{Blue}{\sum_{h_2\in H}\rho(\omega h_2)}\right)+\left(\color{Green}{\sum_{h_2\in H}\rho(\omega^2 h_2)}\right)$$

$$=\begin{array}{ccccc} & \color{Purple}{\rho(1)} & \color{Purple}{+} & \color{Purple}{\rho(\omega)} & \color{Purple}{+} & \color{Purple}{\rho(\omega^2)} \\ + & \color{Blue}{\rho(\omega)} & \color{Blue}{+} & \color{Blue}{\rho(\omega^2)} & \color{Blue}{+} & \color{Blue}{\rho(1)} \\ + & \color{Green}{\rho(\omega^2)} & \color{Green}{+} & \color{Green}{\rho(1)} & \color{Green}{+} & \color{Green}{\rho(\omega)} \end{array} \quad =3\big[\rho(1)+\rho(\omega)+\rho(\omega^2)\big]$$

• @Omar for instance, $(\sum_i a_i)^2=(\sum_i a_i)(\sum_j a_j)=\sum_{i,j}a_ia_j$. same idea. – arctic tern May 3 '16 at 6:07
• @Omar because for all $h\in H$, $\rho(h)$ appears as a summand in $\sum_{h_1,h_2\in H}\rho(h_1h_2)$ a total of $|H|$ times. If it helps, you can think of $x\mapsto h_1x$ as a bijection, hence $$\frac{1}{|H|^2}\sum_{h_1\in H}\left(\sum_{h_2\in H}\rho(h_1h_2)\right)=\frac{1}{|H|^2}\sum_{h_1\in H}\left(\sum_{h_2\in H}\rho(h_2)\right)=\frac{1}{|H|^2}|H|\sum_{h\in H}\rho(h)$$ – arctic tern May 3 '16 at 6:53
• I'll repeat what I said: "for all $h\in H$, $\rho(h)$ appears as a summand in $\sum_{h_1,h_2\in H}\rho(h_1h_2)$ a total of $|H|$ times." This is because we can write any particular $h$ in the form $h_1h_2$ with $h_1,h_2\in H$ a total of $|H|$ many ways. Equivalently, the map $H\times H\to H$ given by $(h_1,h_2)\mapsto h_1h_2$ is an $|H|$-to-$1$ function. I am running out of ways to say the same thing. Also see my previous comment: Do you get why, for any fixed $h_1$, we have $\sum_{h_2\in H}\rho(h_1h_2)=\sum_{h_2\in H}\rho(h_2)$? – arctic tern May 3 '16 at 19:49
• @OmarShehab Because for fixed $h_1$, the map $x\mapsto h_1x$ is a bijection on $H$, and so both sums have exactly the same summands, just possibly in a different order. – arctic tern May 4 '16 at 1:44
• For example, suppose $H$ is the fifth roots of unity generated by a primitive root $\zeta$. If we write $$\sum_{h_2\in H}\rho(h_2)=\rho(1)+\rho(\zeta)+\rho(\zeta^2)+\rho(\zeta^3)+\rho(\zeta^4),$$ and set $h_1=\zeta^2$, then we have $$\sum_{h_2\in H}\rho(h_1h_2)=\rho(\zeta^2)+\rho(\zeta^3)+\rho(\zeta^4)+\rho(1)+\rho(\zeta),$$ which is exactly the same sum, only with its summands permuted. – arctic tern May 4 '16 at 1:51


text:
## Chemistry: The Molecular Science (5th Edition)

First IE of K < Second IE of Be < First IE of Li < First IE of BE < Second IE of Na -First IE of K: Potassium is one away from being a Noble gas, so it makes sense that it has the smallest ionization energy as it wants to lose an electron. -Second IE of Be: After losing an electron, Beryllium is one away from being a Noble gas, so it makes sense that it has the second smallest ionization energy as it wants to lose an electron. Note, this is slightly higher than the first ionization energy of Potassium, for Be has more electrons. - First IE of Li: Li has fewer electrons than Potassium, so even though it is one away from being a noble gas as well, the stronger attraction of the protons increases ionization energy. -First IE of BE: This is not one away from being a noble gas, so it is harder to rip the electron off. -Second IE of Na: $Na^+$ has a noble gas configuration of electrons, so it is hard to rip an electron off. Thus, its second ionization energy is high.