为您推荐:
精华内容
最热下载
问答
  • 5星
    2KB qq_36686437 2021-03-24 13:23:11
  • 5星
    6.77MB cc605523 2020-12-29 14:02:52
  • 5星
    4.36MB weixin_41356941 2021-03-09 15:12:20
  • 5星
    487.12MB weixin_44802353 2021-05-23 12:32:22
  • This blog is only for my personal review of mathematical modeling module. outline1. Why mathematical models?2. What is system?3. What is model and mathematical model?4. Classification of models.5. How...

    This blog is only for my personal review of mathematical modeling module.(lecture notes and personal understandings)

    1. Why mathematical models?

    This is all about complexity. Problems in science and engineering tend to be complex, usually involves a large number of entities, the relationships among entities could also be nightmare. We are craving for a tool that enable us to go more deeper into the problems to get more insight, or on the other hand , learn more about the future with existing data. Modeling allow us to tackle such complexity, or in another words, to simplify problems and make them tractable.

    2. What is system?

    system is as an entity or collection of entity whose properties we want to study. System can be defined alternatively as an assemblage of objects joined in some regular interaction or interdependence. As a modeler, what are the factors we are interested? We need to understand what is the system of interest and how does it work. What causes changes in the system and how sensitive the system is to these changes.

    3. What is model and mathematical model?

    Marvin Minsky defines a model as “To an observer B, an object A ∗ A^* A is a model of object A to the extent that B can use A ∗ A^* A to answer questions of interest about A”.Two interesting implications are worth-mentioning. Firstly, this definition implies that a model is supposed to serve one specific problem or one series of problem. Secondly, model vary as observer changes.

    Apparently, the purposes of modeling are:

    • To answer the question.
    • To solve the problem.

    Mathematical models inherit the same properties of general models, but they are built by mathematical concepts and equations. The reason why we need mathematical model is that we have to make systems observable and measurable. They map relationships between system input and output.

    Modeler are always looking for an easy way out! Never overcomplicate problems! So what is a good model? The best model is the simplest one that still allows us to understand the system and solve problems related to it. Because if a model is overcomplicated, it is hard to capture more insight whereas a model is not able to describe the problem we are dealing with if it is too simple.

    How do people simplify a complex problem? How do we tackle complexity on daily bases? We tend to extract the information that we believe is vital and selectively ignore the others. The same idea is used in simplification for mathematical models. A mathematical model usually takes the shape of {S,Q,M}, S is the system,or a reduced system. Q is a set of questions that we are trying to solve by using the models. M represents a set of solustions (equtions) that can solve Qs.

    Two points should be emphasized here are that the order of {S,Q,M} follows chronology and the model has to be linked to its purposes.

    I came cross a interesting question earlier today. “What is the relationship between mathematical models and linear regression?” It is a stupid question though. From my point of view, a mathematical model is a general term for combination among algorithms to solve a specific problem, whereas linear regression itself is an algorithm, but it could be a complete mathematical model if it is able to solve a problem without combining other algorithms.

    4. Classification of models.

    Models can be classified differently based on their characteristics, there are many kinds of mathematical models:

    starting with most general classifications:
    1.Black-Box Model
    when using this type of model, we cannot get any insight of the model. Only thing we know is that we feed our inputs into the model and we get corresponding outputs. We have no idea what happend in the process, we have no ideas what have our inputs gone through to get this output.
    Just like when we are trying to use ‘SVM’ in ‘Sklearn’ to fit the dataset of ‘iris’. We just use a existing model to fit our data and we get 100% classification rate. We don’t bother how Lagrange multiplier is used and how it manages to find the optimal.

    2.White-Box Model
    we know the input-output mapping and how the relationships or parameters govern the output. In another words, we know 100% what is going on in the process, we know every detail. We know how and why that our inputs are transformed into outputs.

    3. Grey-box Model
    It is at the middle of two extremes mentioning above. Grey-box model is where we start with an unknown process(it is safe to say it starts at a black-box level) and as we carry out more and more experiments(simulations), the details in the process are gradually getting transparent.In another words ,we learn more and more relationships between input and output.

    Mathematical model can be categorised more specifically.

    • Phenomenological model and Mechanistic model
      The formal defination of the former is:

      A mathematical model (S, Q, M) is called phenomenological if it was constructed based on experimental data only, using no a priori information about S.

      The major problem of this kind of model is that “you don’t know what you don’t know”,meaning you don’t know if you are missing any vital parameters.

    • Mechanistic model
      Unlike the former one, when using this type of model, “you know what you should kown”. Formal definiation is :

      A mathematical model (S, Q, M) is called mechanistic if some of the statements in M are based on a priori information about S.

      Models can also be grouped base on time and space.

    • Static and dynamic models
      A mathematical model is a dynamic model if at least one of its parameters depends on time. Otherwise, if any of a system parameter not depend on time, we call that is a static model.

    • lumped and distributed model
      a model can be considered as a distributed model if any of its parameter depends on location. And lumped otherwise.

    5. How to build a model?

    There are several steps we have to follow to build a valid model.
    Figure 1 graphically shows the steps we need to go through:
    在这里插入图片描述

    1. Problem identification.
      Apparently, the first step is to set a or multiple goal(s) that our model needs to serve.
      What we should take into consideration when building a model?
      1.What is (are) the purpose(s) and objective(s) of model we are building?
      2. What is the system?
      3. What information do we have so far. Does it describe system?
      4. what is the criterion that we use to measure outcomes.

    2. System Analysis
      At step of system analysis, we need to focus on data. Are data we have reliable? Are they sufficient? Do we need to collect more data? After we can draw a “layout” of the model, we need to think about how to simplify the model. Simplification is the key! Because it is hopeless to model all the factors in a complex system. The more factors involved, the more combinations will be. Consequently, more experiments, simulations, trials we have to do to guarantee the accuracy. It would require much more recouses and much more time-comsuming.

    3. Formulate Mathematical Model.
      After we understand what is the situation we are dealing with and how much we understand the current data. We then look for the simplest model first. The simplest model is the one that involves the least parameters.

    4. Obtain Mathematical Solutions.
      Use numerical method to solve the model. If the simplest one is good to solve the Qs, then mission accomplished. But if it doesn’t, we tend to complicate our model by gradually adding more related parameters until it satisfies the purposes.

      5.Interpret The Model
      Examine the results. Figure out the robustness of the model.

      6.Compare With Reality.
      How does it perform on the test data? Does solutions make scence? can it be simplified?

    6. Examples

    Following is an example that my lecuturer used in the lecture.

    Suppose we want to model the population of red fox in London. We want know how that population change monthly. Following are some information about red fox in London.
    Initial number of foxes in London: 150
    monthly reproduction rate: r=0.25, monthly death rate: d= 0.1

    What is S ,Q,M.

    My solution:
    S:
    The entire system should involve red foxes and london.

    Q:
    How many red foxes will have in London in month N?

    M:
    F(n)= F(n-1)*(1+r-d), where F() is the population of foxes in month n.

    展开全文
    weixin_52668444 2021-03-01 01:19:26
  • is this deep copy really necessary, because we might want to inspect x later and would be very surprised if x had changed somehow. Did you notice how I just said x three times (four times if ...

    I find it easiest to understand move semantics with example code. Let's start with a very simple string class which only holds a pointer to a heap-allocated block of memory:

    #include <cstring>
    #include <algorithm>
    
    class string
    {
        char* data;
    
    public:
    
        string(const char* p)
        {
            size_t size = strlen(p) + 1;
            data = new char[size];
            memcpy(data, p, size);
        }

    Since we chose to manage the memory ourselves, we need to follow the rule of three. I am going to defer writing the assignment operator and only implement the destructor and the copy constructor for now:

        ~string()
        {
            delete[] data;
        }
    
        string(const string& that)
        {
            size_t size = strlen(that.data) + 1;
            data = new char[size];
            memcpy(data, that.data, size);
        }

    The copy constructor defines what it means to copy string objects. The parameter const string& that binds to all expressions of type string which allows you to make copies in the following examples:

    string a(x);                                    // Line 1
    string b(x + y);                                // Line 2
    string c(some_function_returning_a_string());   // Line 3

    Now comes the key insight into move semantics. Note that only in the first line where we copy x is this deep copy really necessary, because we might want to inspect x later and would be very surprised if x had changed somehow. Did you notice how I just said x three times (four times if you include this sentence) and meant the exact same object every time? We call expressions such as x "lvalues".

    The arguments in lines 2 and 3 are not lvalues, but rvalues, because the underlying string objects have no names, so the client has no way to inspect them again at a later point in time.rvalues denote temporary objects which are destroyed at the next semicolon (to be more precise: at the end of the full-expression that lexically contains the rvalue). This is important because during the initialization of b and c, we could do whatever we wanted with the source string, and the client couldn't tell a difference!

    C++0x introduces a new mechanism called "rvalue reference" which, among other things,allows us to detect rvalue arguments via function overloading. All we have to do is write a constructor with an rvalue reference parameter. Inside that constructor we can do anything we want with the source, as long as we leave it in some valid state:

        string(string&& that)   // string&& is an rvalue reference to a string
        {
            data = that.data;
            that.data = 0;
        }

    What have we done here? Instead of deeply copying the heap data, we have just copied the pointer and then set the original pointer to null. In effect, we have "stolen" the data that originally belonged to the source string. Again, the key insight is that under no circumstance could the client detect that the source had been modified. Since we don't really do a copy here, we call this constructor a "move constructor". Its job is to move resources from one object to another instead of copying them.

    Congratulations, you now understand the basics of move semantics! Let's continue by implementing the assignment operator. If you're unfamiliar with the copy and swap idiom, learn it and come back, because it's an awesome C++ idiom related to exception safety.

        string& operator=(string that)
        {
            std::swap(data, that.data);
            return *this;
        }
    };

    Huh, that's it? "Where's the rvalue reference?" you might ask. "We don't need it here!" is my answer :)

    Note that we pass the parameter that by value, so that has to be initialized just like any other string object. Exactly how is that going to be initialized? In the olden days of C++98, the answer would have been "by the copy constructor". In C++0x, the compiler chooses between the copy constructor and the move constructor based on whether the argument to the assignment operator is an lvalue or an rvalue.

    So if you say a = b, the copy constructor will initialize that (because the expression b is an lvalue), and the assignment operator swaps the contents with a freshly created, deep copy. That is the very definition of the copy and swap idiom -- make a copy, swap the contents with the copy, and then get rid of the copy by leaving the scope. Nothing new here.

    But if you say a = x + y, the move constructor will initialize that (because the expression x + y is an rvalue), so there is no deep copy involved, only an efficient move.that is still an independent object from the argument, but its construction was trivial,since the heap data didn't have to be copied, just moved. It wasn't necessary to copy it because x + y is an rvalue, and again, it is okay to move from string objects denoted by rvalues.

    To summarize, the copy constructor makes a deep copy, because the source must remain untouched.The move constructor, on the other hand, can just copy the pointer and then set the pointer in the source to null. It is okay to "nullify" the source object in this manner, because the client has no way of inspecting the object again.

    I hope this example got the main point across. There is a lot more to rvalue references and move semantics which I intentionally left out to keep it simple. If you want more details please see my supplementary answer.



    My first answer was an extremely simplified introduction to move semantics, and many details were left out on purpose to keep it simple.However, there is a lot more to move semantics, and I thought it was time for a second answer to fill the gaps.The first answer is already quite old, and it did not feel right to simply replace it with a completely different text. I think it still serves well as a first introduction. But if you want to dig deeper, read on :)

    Stephan T. Lavavej took the time provide valuable feedback. Thank you very much, Stephan!

    Introduction

    Move semantics allows an object, under certain conditions, to take ownership of some other object's external resources. This is important in two ways:

    1. Turning expensive copies into cheap moves. See my first answer for an example. Note that if an object does not manage at least one external resource (either directly, or indirectly through its member objects), move semantics will not offer any advantages over copy semantics. In that case, copying an object and moving an object means the exact same thing:

      class cannot_benefit_from_move_semantics
      {
          int a;        // moving an int means copying an int
          float b;      // moving a float means copying a float
          double c;     // moving a double means copying a double
          char d[64];   // moving a char array means copying a char array
      
          // ...
      };
    2. Implementing safe "move-only" types; that is, types for which copying does not make sense, but moving does. Examples include locks, file handles, and smart pointers with unique ownership semantics. Note: This answer discusses std::auto_ptr, a deprecated C++98 standard library template, which was replaced by std::unique_ptr in C++11. Intermediate C++ programmers are probably at least somewhat familiar with std::auto_ptr, and because of the "move semantics" it displays, it seems like a good starting point for discussing move semantics in C++11. YMMV.

    What is a move?

    The C++98 standard library offers a smart pointer with unique ownership semantics called std::auto_ptr<T>. In case you are unfamiliar with auto_ptr, its purpose is to guarantee that a dynamically allocated object is always released, even in the face of exceptions:

    {
        std::auto_ptr<Shape> a(new Triangle);
        // ...
        // arbitrary code, could throw exceptions
        // ...
    }   // <--- when a goes out of scope, the triangle is deleted automatically

    The unusual thing about auto_ptr is its "copying" behavior:

    auto_ptr<Shape> a(new Triangle);
    
          +---------------+
          | triangle data |
          +---------------+
            ^
            |
            |
            |
      +-----|---+
      |   +-|-+ |
    a | p | | | |
      |   +---+ |
      +---------+
    
    auto_ptr<Shape> b(a);
    
          +---------------+
          | triangle data |
          +---------------+
            ^
            |
            +----------------------+
                                   |
      +---------+            +-----|---+
      |   +---+ |            |   +-|-+ |
    a | p |   | |          b | p | | | |
      |   +---+ |            |   +---+ |
      +---------+            +---------+

    Note how the initialization of b with a does not copy the triangle, but instead transfers the ownership of the triangle from a to b. We also say "a is moved into b" or "the triangle is moved from a to b". This may sound confusing, because the triangle itself always stays at the same place in memory.

    To move an object means to transfer ownership of some resource it manages to another object.

    The copy constructor of auto_ptr probably looks something like this (somewhat simplified):

    auto_ptr(auto_ptr& source)   // note the missing const
    {
        p = source.p;
        source.p = 0;   // now the source no longer owns the object
    }

    Dangerous and harmless moves

    The dangerous thing about auto_ptr is that what syntactically looks like a copy is actually a move. Trying to call a member function on a moved-from auto_ptr will invoke undefined behavior, so you have to be very careful not to use an auto_ptr after it has been moved from:

    auto_ptr<Shape> a(new Triangle);   // create triangle
    auto_ptr<Shape> b(a);              // move a into b
    double area = a->area();           // undefined behavior

    But auto_ptr is not always dangerous. Factory functions are a perfectly fine use case for auto_ptr:

    auto_ptr<Shape> make_triangle()
    {
        return auto_ptr<Shape>(new Triangle);
    }
    
    auto_ptr<Shape> c(make_triangle());      // move temporary into c
    double area = make_triangle()->area();   // perfectly safe

    Note how both examples follow the same syntactic pattern:

    auto_ptr<Shape> variable(expression);
    double area = expression->area();

    And yet, one of them invokes undefined behavior, whereas the other one does not. So what is the difference between the expressions a and make_triangle()? Aren't they both of the same type? Indeed they are, but they have different value categories.

    Value categories

    Obviously, there must be some profound difference between the expression a which denotes an auto_ptr variable, and the expression make_triangle() which denotes the call of a function that returns an auto_ptr by value, thus creating a fresh temporary auto_ptr object every time it is called. a is an example of an lvalue, whereas make_triangle() is an example of an rvalue.

    Moving from lvalues such as a is dangerous, because we could later try to call a member function via a, invoking undefined behavior. On the other hand, moving from rvalues such as make_triangle() is perfectly safe, because after the copy constructor has done its job, we cannot use the temporary again. There is no expression that denotes said temporary; if we simply write make_triangle() again, we get a different temporary. In fact, the moved-from temporary is already gone on the next line:

    auto_ptr<Shape> c(make_triangle());
                                      ^ the moved-from temporary dies right here

    Note that the letters l and r have a historic origin in the left-hand side and right-hand side of an assignment. This is no longer true in C++, because there are lvalues which cannot appear on the left-hand side of an assignment (like arrays or user-defined types without an assignment operator), and there are rvalues which can (all rvalues of class types with an assignment operator).

    An rvalue of class type is an expression whose evaluation creates a temporary object. Under normal circumstances, no other expression inside the same scope denotes the same temporary object.

    Rvalue references

    We now understand that moving from lvalues is potentially dangerous, but moving from rvalues is harmless. If C++ had language support to distinguish lvalue arguments from rvalue arguments, we could either completely forbid moving from lvalues, or at least make moving from lvalues explicit at call site, so that we no longer move by accident.

    C++11's answer to this problem is rvalue references. An rvalue reference is a new kind of reference that only binds to rvalues, and the syntax is X&&. The good old reference X& is now known as an lvalue reference. (Note that X&& is not a reference to a reference; there is no such thing in C++.)

    If we throw const into the mix, we already have four different kinds of references. What kinds of expressions of type X can they bind to?

                lvalue   const lvalue   rvalue   const rvalue
    ---------------------------------------------------------              
    X&          yes
    const X&    yes      yes            yes      yes
    X&&                                 yes
    const X&&                           yes      yes

    In practice, you can forget about const X&&. Being restricted to read from rvalues is not very useful.

    An rvalue reference X&& is a new kind of reference that only binds to rvalues.

    Implicit conversions

    Rvalue references went through several versions. Since version 2.1, an rvalue reference X&& also binds to all value categories of a different type Y, provided there is an implicit conversion from Y to X. In that case, a temporary of type X is created, and the rvalue reference is bound to that temporary:

    void some_function(std::string&& r);
    
    some_function("hello world");

    In the above example, "hello world" is an lvalue of type const char[12]. Since there is an implicit conversion from const char[12] through const char* to std::string, a temporary of type std::string is created, and r is bound to that temporary. This is one of the cases where the distinction between rvalues (expressions) and temporaries (objects) is a bit blurry.

    Move constructors

    A useful example of a function with an X&& parameter is the move constructor X::X(X&& source). Its purpose is to transfer ownership of the managed resource from the source into the current object.

    In C++11, std::auto_ptr<T> has been replaced by std::unique_ptr<T> which takes advantage of rvalue references. I will develop and discuss a simplified version of unique_ptr. First, we encapsulate a raw pointer and overload the operators -> and *, so our class feels like a pointer:

    template<typename T>
    class unique_ptr
    {
        T* ptr;
    
    public:
    
        T* operator->() const
        {
            return ptr;
        }
    
        T& operator*() const
        {
            return *ptr;
        }

    The constructor takes ownership of the object, and the destructor deletes it:

        explicit unique_ptr(T* p = nullptr)
        {
            ptr = p;
        }
    
        ~unique_ptr()
        {
            delete ptr;
        }

    Now comes the interesting part, the move constructor:

        unique_ptr(unique_ptr&& source)   // note the rvalue reference
        {
            ptr = source.ptr;
            source.ptr = nullptr;
        }

    This move constructor does exactly what the auto_ptr copy constructor did, but it can only be supplied with rvalues:

    unique_ptr<Shape> a(new Triangle);
    unique_ptr<Shape> b(a);                 // error
    unique_ptr<Shape> c(make_triangle());   // okay

    The second line fails to compile, because a is an lvalue, but the parameter unique_ptr&& source can only be bound to rvalues. This is exactly what we wanted; dangerous moves should never be implicit. The third line compiles just fine, because make_triangle() is an rvalue. The move constructor will transfer ownership from the temporary to c. Again, this is exactly what we wanted.

    The move constructor transfers ownership of a managed resource into the current object.

    Move assignment operators

    The last missing piece is the move assignment operator. Its job is to release the old resource and acquire the new resource from its argument:

        unique_ptr& operator=(unique_ptr&& source)   // note the rvalue reference
        {
            if (this != &source)    // beware of self-assignment
            {
                delete ptr;         // release the old resource
    
                ptr = source.ptr;   // acquire the new resource
                source.ptr = nullptr;
            }
            return *this;
        }
    };

    Note how this implementation of the move assignment operator duplicates logic of both the destructor and the move constructor. Are you familiar with the copy-and-swap idiom? It can also be applied to move semantics as the move-and-swap idiom:

        unique_ptr& operator=(unique_ptr source)   // note the missing reference
        {
            std::swap(ptr, source.ptr);
            return *this;
        }
    };

    Now that source is a variable of type unique_ptr, it will be initialized by the move constructor; that is, the argument will be moved into the parameter. The argument is still required to be an rvalue, because the move constructor itself has an rvalue reference parameter. When control flow reaches the closing brace of operator=, source goes out of scope, releasing the old resource automatically.

    The move assignment operator transfers ownership of a managed resource into the current object, releasing the old resource. The move-and-swap idiom simplifies the implementation.

    Moving from lvalues

    Sometimes, we want to move from lvalues. That is, sometimes we want the compiler to treat an lvalue as if it were an rvalue, so it can invoke the move constructor, even though it could be potentially unsafe.For this purpose, C++11 offers a standard library function template called std::move inside the header <utility>.This name is a bit unfortunate, because std::move simply casts an lvalue to an rvalue; it does not move anything by itself. It merely enables moving. Maybe it should have been named std::cast_to_rvalue or std::enable_move, but we are stuck with the name by now.

    Here is how you explicitly move from an lvalue:

    unique_ptr<Shape> a(new Triangle);
    unique_ptr<Shape> b(a);              // still an error
    unique_ptr<Shape> c(std::move(a));   // okay

    Note that after the third line, a no longer owns a triangle. That's okay, because by explicitly writing std::move(a), we made our intentions clear: "Dear constructor, do whatever you want with a in order to initialize c; I don't care about a anymore. Feel free to have your way with a."

    std::move(some_lvalue) casts an lvalue to an rvalue, thus enabling a subsequent move.

    Xvalues

    Note that even though std::move(a) is an rvalue, its evaluation does not create a temporary object. This conundrum forced the committee to introduce a third value category. Something that can be bound to an rvalue reference, even though it is not an rvalue in the traditional sense, is called an xvalue (eXpiring value). The traditional rvalues were renamed to prvalues (Pure rvalues).

    Both prvalues and xvalues are rvalues. Xvalues and lvalues are both glvalues (Generalized lvalues). The relationships are easier to grasp with a diagram:

            expressions
              /     \
             /       \
            /         \
        glvalues   rvalues
          /  \       /  \
         /    \     /    \
        /      \   /      \
    lvalues   xvalues   prvalues

    Note that only xvalues are really new; the rest is just due to renaming and grouping.

    C++98 rvalues are known as prvalues in C++11. Mentally replace all occurrences of "rvalue" in the preceding paragraphs with "prvalue".

    Moving out of functions

    So far, we have seen movement into local variables, and into function parameters. But moving is also possible in the opposite direction. If a function returns by value, some object at call site (probably a local variable or a temporary, but could be any kind of object) is initialized with the expression after the return statement as an argument to the move constructor:

    unique_ptr<Shape> make_triangle()
    {
        return unique_ptr<Shape>(new Triangle);
    }          \-----------------------------/
                      |
                      | temporary is moved into c
                      |
                      v
    unique_ptr<Shape> c(make_triangle());

    Perhaps surprisingly, automatic objects (local variables that are not declared as static) can also be implicitly moved out of functions:

    unique_ptr<Shape> make_square()
    {
        unique_ptr<Shape> result(new Square);
        return result;   // note the missing std::move
    }

    How come the move constructor accepts the lvalue result as an argument? The scope of result is about to end, and it will be destroyed during stack unwinding. Nobody could possibly complain afterwards that result had changed somehow; when control flow is back at the caller, result does not exist anymore! For that reason, C++11 has a special rule that allows returning automatic objects from functions without having to write std::move. In fact, you should never use std::move to move automatic objects out of functions, as this inhibits the "named return value optimization" (NRVO).

    Never use std::move to move automatic objects out of functions.

    Note that in both factory functions, the return type is a value, not an rvalue reference. Rvalue references are still references, and as always, you should never return a reference to an automatic object; the caller would end up with a dangling reference if you tricked the compiler into accepting your code, like this:

    unique_ptr<Shape>&& flawed_attempt()   // DO NOT DO THIS!
    {
        unique_ptr<Shape> very_bad_idea(new Square);
        return std::move(very_bad_idea);   // WRONG!
    }

    Never return automatic objects by rvalue reference. Moving is exclusively performed by the move constructor, not by std::move, and not by merely binding an rvalue to an rvalue reference.

    Moving into members

    Sooner or later, you are going to write code like this:

    class Foo
    {
        unique_ptr<Shape> member;
    
    public:
    
        Foo(unique_ptr<Shape>&& parameter)
        : member(parameter)   // error
        {}
    };

    Basically, the compiler will complain that parameter is an lvalue. If you look at its type, you see an rvalue reference, but an rvalue reference simply means "a reference that is bound to an rvalue"; it does not mean that the reference itself is an rvalue! Indeed, parameter is just an ordinary variable with a name. You can use parameter as often as you like inside the body of the constructor, and it always denotes the same object. Implicitly moving from it would be dangerous, hence the language forbids it.

    A named rvalue reference is an lvalue, just like any other variable.

    The solution is to manually enable the move:

    class Foo
    {
        unique_ptr<Shape> member;
    
    public:
    
        Foo(unique_ptr<Shape>&& parameter)
        : member(std::move(parameter))   // note the std::move
        {}
    };

    You could argue that parameter is not used anymore after the initialization of member. Why is there no special rule to silently insert std::move just as with return values? Probably because it would be too much burden on the compiler implementors. For example, what if the constructor body was in another translation unit? By contrast, the return value rule simply has to check the symbol tables to determine whether or not the identifier after the return keyword denotes an automatic object.

    You can also pass parameter by value. For move-only types like unique_ptr, it seems there is no established idiom yet. Personally, I prefer pass by value, as it causes less clutter in the interface.

    Special member functions

    C++98 implicitly declares three special member functions on demand, that is, when they are needed somewhere: the copy constructor, the copy assignment operator and the destructor.

    X::X(const X&);              // copy constructor
    X& X::operator=(const X&);   // copy assignment operator
    X::~X();                     // destructor

    Rvalue references went through several versions. Since version 3.0, C++11 declares two additional special member functions on demand: the move constructor and the move assignment operator. Note that neither VC10 nor VC11 conform to version 3.0 yet, so you will have to implement them yourself.

    X::X(X&&);                   // move constructor
    X& X::operator=(X&&);        // move assignment operator

    These two new special member functions are only implicitly declared if none of the special member functions are declared manually. Also, if you declare your own move constructor or move assignment operator, neither the copy constructor nor the copy assignment operator will be declared implicitly.

    What do these rules mean in practice?

    If you write a class without unmanaged resources, there is no need to declare any of the five special member functions yourself, and you will get correct copy semantics and move semantics for free. Otherwise, you will have to implement the special member functions yourself. Of course, if your class does not benefit from move semantics, there is no need to implement the special move operations.

    Note that the copy assignment operator and the move assignment operator can be fused into a single, unified assignment operator, taking its argument by value:

    X& X::operator=(X source)    // unified assignment operator
    {
        swap(source);            // see my first answer for an explanation
        return *this;
    }

    This way, the number of special member functions to implement drops from five to four. There is a tradeoff between exception-safety and efficiency here, but I am not an expert on this issue.

    Universal references

    Consider the following function template:

    template<typename T>
    void foo(T&&);

    You might expect T&& to only bind to rvalues, because at first glance, it looks like an rvalue reference. As it turns out though, T&& also binds to lvalues:

    foo(make_triangle());   // T is unique_ptr<Shape>, T&& is unique_ptr<Shape>&&
    unique_ptr<Shape> a(new Triangle);
    foo(a);                 // T is unique_ptr<Shape>&, T&& is unique_ptr<Shape>&

    If the argument is an rvalue of type X, T is deduced to be X, hence T&& means X&&. This is what anyone would expect.But if the argument is an lvalue of type X, due to a special rule, T is deduced to be X&, hence T&& would mean something like X& &&. But since C++ still has no notion of references to references, the type X& && is collapsed into X&. This may sound confusing and useless at first, but reference collapsing is essential for perfect forwarding (which will not be discussed here).

    T&& is not an rvalue reference, but a universal reference. It also binds to lvalues, in which case T and T&& are both lvalue references.

    If you want to constrain a function template to rvalues, you can combine SFINAE with type traits:

    #include <type_traits>
    
    template<typename T>
    typename std::enable_if<std::is_rvalue_reference<T&&>::value, void>::type
    foo(T&&);

    Implementation of move

    Now that you understand reference collapsing, here is how std::move is implemented:

    template<typename T>
    typename std::remove_reference<T>::type&&
    move(T&& t)
    {
        return static_cast<typename std::remove_reference<T>::type&&>(t);
    }

    As you can see, move accepts any kind of parameter thanks to the universal reference T&&, and it returns an rvalue reference. The std::remove_reference<T>::type meta-function call is necessary because otherwise, for lvalues of type X, the return type would be X& &&, which would collapse into X&. Since t is always an lvalue (remember that a named rvalue reference is an lvalue), but we want to bind t to an rvalue reference, we have to explicitly cast t to the correct return type.The call of a function that returns an rvalue reference is itself an xvalue. Now you know where xvalues come from ;)

    The call of a function that returns an rvalue reference, such as std::move, is an xvalue.

    Note that returning by rvalue reference is fine in this example, because t does not denote an automatic object, but instead an object that was passed in by the caller.


    展开全文
    metasearch 2013-11-24 22:42:41
  • Here are some ideas to get you started: 1. Stop spending time with the wrong people... – Life is too short to spend time with people who suck the happiness out of you. If someone wants you in t

    Here are some ideas to get you started:


    1. Stop spending time with the wrong people. – Life is too short to spend time with people who suck the happiness out of you. If someone wants you in their life, they’ll make room for you. You shouldn’t have to fight for a spot. Never, ever insist yourself to someone who continuously overlooks your worth. And remember, it’s not the people that stand by your side when you’re at your best, but the ones who stand beside you when you’re at your worst that are your true friends.

    2. Stop running from your problems. – Face them head on. No, it won’t be easy. There is no person in the world capable of flawlessly handling every punch thrown at them. We aren’t supposed to be able to instantly solve problems. That’s not how we’re made. In fact, we’re made to get upset, sad, hurt, stumble and fall. Because that’s the whole purpose of living – to face problems, learn, adapt, and solve them over the course of time. This is what ultimately molds us into the person we become.

    3. Stop lying to yourself. – You can lie to anyone else in the world, but you can’t lie to yourself. Our lives improve only when we take chances, and the first and most difficult chance we can take is to be honest with ourselves. Read The Road Less Traveled.

    4. Stop putting your own needs on the back burner. – The most painful thing is losing yourself in the process of loving someone too much, and forgetting that you are special too. Yes, help others; but help yourself too. If there was ever a moment to follow your passion and do something that matters to you, that moment is now.

    5. Stop trying to be someone you’re not. – One of the greatest challenges in life is being yourself in a world that’s trying to make you like everyone else. Someone will always be prettier, someone will always be smarter, someone will always be younger, but they will never be you. Don’t change so people will like you. Be yourself and the right people will love the real you.

    6. Stop trying to hold onto the past. – You can’t start the next chapter of your life if you keep re-reading your last one.

    7. Stop being scared to make a mistake. – Doing something and getting it wrong is at least ten times more productive than doing nothing. Every success has a trail of failures behind it, and every failure is leading towards success. You end up regretting the things you did NOT do far more than the things you did.

    8. Stop berating yourself for old mistakes. – We may love the wrong person and cry about the wrong things, but no matter how things go wrong, one thing is for sure, mistakes help us find the person and things that are right for us. We all make mistakes, have struggles, and even regret things in our past. But you are not your mistakes, you are not your struggles, and you are here NOW with the power to shape your day and your future. Every single thing that has ever happened in your life is preparing you for a moment that is yet to come.

    9. Stop trying to buy happiness. – Many of the things we desire are expensive. But the truth is, the things that really satisfy us are totally free – love, laughter and working on our passions.

    10. Stop exclusively looking to others for happiness. – If you’re not happy with who you are on the inside, you won’t be happy in a long-term relationship with anyone else either. You have to create stability in your own life first before you can share it with someone else. Read Stumbling on Happiness.

    11. Stop being idle. – Don’t think too much or you’ll create a problem that wasn’t even there in the first place. Evaluate situations and take decisive action. You cannot change what you refuse to confront. Making progress involves risk. Period! You can’t make it to second base with your foot on first.

    12. Stop thinking you’re not ready. – Nobody ever feels 100% ready when an opportunity arises. Because most great opportunities in life force us to grow beyond our comfort zones, which means we won’t feel totally comfortable at first.

    13. Stop getting involved in relationships for the wrong reasons. – Relationships must be chosen wisely. It’s better to be alone than to be in bad company. There’s no need to rush. If something is meant to be, it will happen – in the right time, with the right person, and for the best reason. Fall in love when you’re ready, not when you’re lonely.

    14. Stop rejecting new relationships just because old ones didn’t work. – In life you’ll realize that there is a purpose for everyone you meet. Some will test you, some will use you and some will teach you. But most importantly, some will bring out the best in you.

    15. Stop trying to compete against everyone else. – Don’t worry about what others are doing better than you. Concentrate on beating your own records every day. Success is a battle between YOU and YOURSELF only.

    16. Stop being jealous of others. – Jealousy is the art of counting someone else’s blessings instead of your own. Ask yourself this: “What’s something I have that everyone wants?”

    17. Stop complaining and feeling sorry for yourself. – Life’s curveballs are thrown for a reason – to shift your path in a direction that is meant for you. You may not see or understand everything the moment it happens, and it may be tough. But reflect back on those negative curveballs thrown at you in the past. You’ll often see that eventually they led you to a better place, person, state of mind, or situation. So smile! Let everyone know that today you are a lot stronger than you were yesterday, and you will be.

    18. Stop holding grudges. – Don’t live your life with hate in your heart. You will end up hurting yourself more than the people you hate. Forgiveness is not saying, “What you did to me is okay.” It is saying, “I’m not going to let what you did to me ruin my happiness forever.” Forgiveness is the answer… let go, find peace, liberate yourself! And remember, forgiveness is not just for other people, it’s for you too. If you must, forgive yourself, move on and try to do better next time.

    19. Stop letting others bring you down to their level. – Refuse to lower your standards to accommodate those who refuse to raise theirs.

    20. Stop wasting time explaining yourself to others. – Your friends don’t need it and your enemies won’t believe it anyway. Just do what you know in your heart is right.

    21. Stop doing the same things over and over without taking a break. – The time to take a deep breath is when you don’t have time for it. If you keep doing what you’re doing, you’ll keep getting what you’re getting. Sometimes you need to distance yourself to see things clearly.

    22. Stop overlooking the beauty of small moments. – Enjoy the little things, because one day you may look back and discover they were the big things. The best portion of your life will be the small, nameless moments you spend smiling with someone who matters to you.

    23. Stop trying to make things perfect. – The real world doesn’t reward perfectionists; it rewards people who get things done. 

    24. Stop following the path of least resistance. – Life is not easy, especially when you plan on achieving something worthwhile. Don’t take the easy way out. Do something extraordinary.

    25. Stop acting like everything is fine if it isn’t. – It’s okay to fall apart for a little while. You don’t always have to pretend to be strong, and there is no need to constantly prove that everything is going well. You shouldn’t be concerned with what other people are thinking either – cry if you need to – it’s healthy to shed your tears. The sooner you do, the sooner you will be able to smile again.

    26. Stop blaming others for your troubles. – The extent to which you can achieve your dreams depends on the extent to which you take responsibility for your life. When you blame others for what you’re going through, you deny responsibility – you give others power over that part of your life.

    27. Stop trying to be everything to everyone. – Doing so is impossible, and trying will only burns you out. But making one person smile CAN change the world. May be not the whole world, but their world. So narrow your focus.

    28. Stop worrying so much. – Worry will not strip tomorrow of its burdens, it will strip today of its joy. One way to check if something is worth mulling over is to ask yourself this question: “Will this matter in one year’s time? Three years? Five years?” If not, then it’s not worth worrying about.

    29. Stop focusing on what you don’t want to happen. – Focus on what you do want to happen. Positive thinking is at the forefront of every great success story. If you awake every morning with the thought that something wonderful will happen in your life today, and you pay close attention, you’ll often find that you’re right.

    30. Stop being ungrateful. – No matter how good or bad you have it, wake up each day thankful for your life. Someone somewhere else is desperately fighting for theirs. Instead of thinking about what you’re missing, try thinking about what you have that everyone else is missing.

    展开全文
    violethill 2014-05-29 22:11:41
  • What is expected value ( N, T) for the above array? – falsetru Jan 9 '14 at 9:09 size(X) returns the size of matrix X in separate variables m and n in matlab. so [n,T] = size(X) will give size of ...

    how to create an array to numpy array?

    def test(X, N):

    [n,T] = X.shape

    print "n : ", n

    print "T : ", T

    if __name__=="__main__":

    X = [[[-9.035250067710876], [7.453250169754028], [33.34074878692627]], [[-6.63700008392334], [5.132999956607819], [31.66075038909912]], [[-5.1272499561309814], [8.251499891281128], [30.925999641418457]]]

    N = 200

    test(X, N)

    I am getting error as

    AttributeError: 'list' object has no attribute 'shape'

    So, I think I need to convert my X to numpy array?

    python

    list

    numpy

    |

    this question

    edited Feb 21 '16 at 13:38

    falsetru 191k 24 260 299 asked Jan 9 '14 at 9:01

    sam 3,266 12 40 68

    |

    2 Answers

    2

    ---Accepted---Accepted---Accepted---

    Use numpy.array to use shape attribute.

    >>> import numpy as np

    >>> X = np.array([

    ... [[-9.035250067710876], [7.453250169754028], [33.34074878692627]],

    ... [[-6.63700008392334], [5.132999956607819], [31.66075038909912]],

    ... [[-5.1272499561309814], [8.251499891281128], [30.925999641418457]]

    ... ])

    >>> X.shape

    (3L, 3L, 1L)

    NOTE X.shape returns 3-items tuple for the given array; [n, T] = X.shape raises ValueError.lib2from BeautifulSoup import BeautifulSoupf = open('airport_temp.tsv', 'w')f.write("Location" + "\t" + "High Temp (F)" + "\t" + "Low Temp (F)" + "\t" + "Mean Humidity" + "\n" )eventually parse from http://www.wunderground.com/histor

    |

    this answer

    edited Jan 9 '14 at 9:09 answered Jan 9 '14 at 9:04

    falsetru 191k 24 260 299      then what if I want to get value of n and T since I am converting code from matlab, which has function [n,T] = size(X);. –

    sam Jan 9 '14 at 9:07 1   @sam, I don't know matlab. What is expected value (

    N,

    T) for the above array? –

    falsetru Jan 9 '14 at 9:09      size(X) returns the size of matrix X in separate variables m and n in matlab. so [n,T] = size(X) will give size of array –

    sam Jan 9 '14 at 9:10      @sam, I mean ... let me know that specific size for the given list.

    9,

    3?

    3,

    3? –

    falsetru Jan 9 '14 at 9:12 1   @sam, Using

    X.shape. ;) –

    falsetru Jan 9 '14 at 9:21

    |

    show more comments

    import numpy

    X = numpy.array(the_big_nested_list_you_had)

    It's still not going to do what you want; you have more bugs, like trying to unpack a 3-dimensional shape into two target variables in test.

    |

    this answer answered Jan 9 '14 at 9:04

    user2357112 90.4k 7 67 137

    |

    ('-joined_at',) @classmethod def create_user(cls,user_name,email,password, admin=False): try: cls.create( user_name=user_name, email=email, password=generate_pass

    展开全文
    weixin_35705382 2021-02-10 16:33:10
  • weixin_32836713 2020-12-23 14:07:43
  • qingzhuyuxian 2019-03-04 15:50:11
  • xiyangxia666hui 2021-03-09 23:54:44
  • weixin_39642990 2020-12-23 13:56:42
  • monica12 2017-06-17 08:13:49
  • qq_31967569 2021-01-04 16:32:55
  • m0_46156900 2021-08-25 08:56:13
  • hpdlzu80100 2021-11-10 16:24:12
  • liukuan73 2017-12-23 11:32:13
  • qq_35082030 2017-09-05 19:33:57
  • iamzhangzhuping 2016-06-16 21:55:59
  • qian_chun_qiang 2018-04-02 15:42:30
  • weixin_28772667 2021-03-18 08:51:12
  • csharp25 2018-12-02 15:21:47
  • xiewenbo 2018-11-07 12:02:23
  • sleks 2012-11-15 08:59:12
  • m0_46156900 2021-09-13 10:00:55
  • qq_41185868 2020-05-31 09:53:29
  • weixin_28848795 2021-04-14 03:31:15
  • Time888 2017-08-31 09:40:39
  • u014546828 2021-12-14 14:31:50
  • shanglianlm 2015-07-07 10:47:58
  • weixin_29455479 2021-03-08 07:45:35
  • weixin_26745985 2020-09-05 03:48:29
  • Sophia_11 2021-08-02 19:31:24
  • weixin_27215337 2021-01-30 07:54:52

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,666
精华内容 7,466
关键字:

isshapethiswhat